ASoC/SoundWire: dai: expand 'stream' concept beyond SoundWire
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Fri, 24 Dec 2021 02:10:31 +0000 (10:10 +0800)
committerSalvatore Bonaccorso <carnil@debian.org>
Sat, 21 Jan 2023 14:35:48 +0000 (14:35 +0000)
Origin: https://git.kernel.org/linus/e8444560b4d9302a511f0996f4cfdf85b628f4ca
Bug-Debian: https://bugs.debian.org/1027430
Bug-Debian: https://bugs.debian.org/1027483

The HDAudio ASoC support relies on the set_tdm_slots() helper to store
the HDaudio stream tag in the tx_mask. This only works because of the
pre-existing order in soc-pcm.c, where the hw_params() is handled for
codec_dais *before* cpu_dais. When the order is reversed, the
stream_tag is used as a mask in the codec fixup functions:

/* fixup params based on TDM slot masks */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
    codec_dai->tx_mask)
soc_pcm_codec_params_fixup(&codec_params,
   codec_dai->tx_mask);

As a result of this confusion, the codec_params_fixup() ends-up
generating bad channel masks, depending on what stream_tag was
allocated.

We could add a flag to state that the tx_mask is really not a mask,
but it would be quite ugly to persist in overloading concepts.

Instead, this patch suggests a more generic get/set 'stream' API based
on the existing model for SoundWire. We can expand the concept to
store 'stream' opaque information that is specific to different DAI
types. In the case of HDAudio DAIs, we only need to store a stream tag
as an unsigned char pointer. The TDM rx_ and tx_masks should really
only be used to store masks.

Rename get_sdw_stream/set_sdw_stream callbacks and helpers as
get_stream/set_stream. No functionality change beyond the rename.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Acked-By: Vinod Koul <vkoul@kernel.org>
Link: https://lore.kernel.org/r/20211224021034.26635-5-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Gbp-Pq: Topic bugfix/all
Gbp-Pq: Name ASoC-SoundWire-dai-expand-stream-concept-beyond-Soun.patch

13 files changed:
drivers/soundwire/intel.c
drivers/soundwire/qcom.c
drivers/soundwire/stream.c
include/sound/soc-dai.h
sound/soc/codecs/max98373-sdw.c
sound/soc/codecs/rt1308-sdw.c
sound/soc/codecs/rt5682-sdw.c
sound/soc/codecs/rt700.c
sound/soc/codecs/rt711.c
sound/soc/codecs/rt715.c
sound/soc/codecs/wsa881x.c
sound/soc/intel/boards/sof_sdw.c
sound/soc/qcom/sdm845.c

index 942d2fe132181fbdc8b3347eeb31de07246c6b81..4487fbb8f2e616a90f34302e3fc19655858de273 100644 (file)
@@ -1140,8 +1140,8 @@ static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
        .prepare = intel_prepare,
        .hw_free = intel_hw_free,
        .shutdown = intel_shutdown,
-       .set_sdw_stream = intel_pcm_set_sdw_stream,
-       .get_sdw_stream = intel_get_sdw_stream,
+       .set_stream = intel_pcm_set_sdw_stream,
+       .get_stream = intel_get_sdw_stream,
 };
 
 static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
@@ -1150,8 +1150,8 @@ static const struct snd_soc_dai_ops intel_pdm_dai_ops = {
        .prepare = intel_prepare,
        .hw_free = intel_hw_free,
        .shutdown = intel_shutdown,
-       .set_sdw_stream = intel_pdm_set_sdw_stream,
-       .get_sdw_stream = intel_get_sdw_stream,
+       .set_stream = intel_pdm_set_sdw_stream,
+       .get_stream = intel_get_sdw_stream,
 };
 
 static const struct snd_soc_component_driver dai_component = {
index 6d22df01f35471e8a8803c09d6ea074a756e9734..ac73258792e6c02541494ecca2108060e31d5f8d 100644 (file)
@@ -649,8 +649,8 @@ static int qcom_swrm_startup(struct snd_pcm_substream *substream,
        ctrl->sruntime[dai->id] = sruntime;
 
        for_each_rtd_codec_dais(rtd, i, codec_dai) {
-               ret = snd_soc_dai_set_sdw_stream(codec_dai, sruntime,
-                                                substream->stream);
+               ret = snd_soc_dai_set_stream(codec_dai, sruntime,
+                                            substream->stream);
                if (ret < 0 && ret != -ENOTSUPP) {
                        dev_err(dai->dev, "Failed to set sdw stream on %s",
                                codec_dai->name);
@@ -676,8 +676,8 @@ static const struct snd_soc_dai_ops qcom_swrm_pdm_dai_ops = {
        .hw_free = qcom_swrm_hw_free,
        .startup = qcom_swrm_startup,
        .shutdown = qcom_swrm_shutdown,
-       .set_sdw_stream = qcom_swrm_set_sdw_stream,
-       .get_sdw_stream = qcom_swrm_get_sdw_stream,
+       .set_stream = qcom_swrm_set_sdw_stream,
+       .get_stream = qcom_swrm_get_sdw_stream,
 };
 
 static const struct snd_soc_component_driver qcom_swrm_dai_component = {
index 304ff2ee7d75a23c9aee0c39205b0c15461c35bc..79554d28f08aa8df0e79c7b0b343821aef94f117 100644 (file)
@@ -1860,7 +1860,7 @@ static int set_stream(struct snd_pcm_substream *substream,
 
        /* Set stream pointer on all DAIs */
        for_each_rtd_dais(rtd, i, dai) {
-               ret = snd_soc_dai_set_sdw_stream(dai, sdw_stream, substream->stream);
+               ret = snd_soc_dai_set_stream(dai, sdw_stream, substream->stream);
                if (ret < 0) {
                        dev_err(rtd->dev, "failed to set stream pointer on dai %s", dai->name);
                        break;
@@ -1931,7 +1931,7 @@ void sdw_shutdown_stream(void *sdw_substream)
        /* Find stream from first CPU DAI */
        dai = asoc_rtd_to_cpu(rtd, 0);
 
-       sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
+       sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
 
        if (IS_ERR(sdw_stream)) {
                dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
index 2150bd4c7a056494286db9c88440b404782e7435..fe86172e860207b2bc7c12f49469d929851187b4 100644 (file)
@@ -239,9 +239,9 @@ struct snd_soc_dai_ops {
                        unsigned int *rx_num, unsigned int *rx_slot);
        int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
 
-       int (*set_sdw_stream)(struct snd_soc_dai *dai,
-                       void *stream, int direction);
-       void *(*get_sdw_stream)(struct snd_soc_dai *dai, int direction);
+       int (*set_stream)(struct snd_soc_dai *dai,
+                         void *stream, int direction);
+       void *(*get_stream)(struct snd_soc_dai *dai, int direction);
 
        /*
         * DAI digital mute - optional.
@@ -446,42 +446,42 @@ static inline void *snd_soc_dai_get_drvdata(struct snd_soc_dai *dai)
 }
 
 /**
- * snd_soc_dai_set_sdw_stream() - Configures a DAI for SDW stream operation
+ * snd_soc_dai_set_stream() - Configures a DAI for stream operation
  * @dai: DAI
- * @stream: STREAM
+ * @stream: STREAM (opaque structure depending on DAI type)
  * @direction: Stream direction(Playback/Capture)
- * SoundWire subsystem doesn't have a notion of direction and we reuse
+ * Some subsystems, such as SoundWire, don't have a notion of direction and we reuse
  * the ASoC stream direction to configure sink/source ports.
  * Playback maps to source ports and Capture for sink ports.
  *
  * This should be invoked with NULL to clear the stream set previously.
  * Returns 0 on success, a negative error code otherwise.
  */
-static inline int snd_soc_dai_set_sdw_stream(struct snd_soc_dai *dai,
-                               void *stream, int direction)
+static inline int snd_soc_dai_set_stream(struct snd_soc_dai *dai,
+                                        void *stream, int direction)
 {
-       if (dai->driver->ops->set_sdw_stream)
-               return dai->driver->ops->set_sdw_stream(dai, stream, direction);
+       if (dai->driver->ops->set_stream)
+               return dai->driver->ops->set_stream(dai, stream, direction);
        else
                return -ENOTSUPP;
 }
 
 /**
- * snd_soc_dai_get_sdw_stream() - Retrieves SDW stream from DAI
+ * snd_soc_dai_get_stream() - Retrieves stream from DAI
  * @dai: DAI
  * @direction: Stream direction(Playback/Capture)
  *
  * This routine only retrieves that was previously configured
- * with snd_soc_dai_get_sdw_stream()
+ * with snd_soc_dai_get_stream()
  *
  * Returns pointer to stream or an ERR_PTR value, e.g.
  * ERR_PTR(-ENOTSUPP) if callback is not supported;
  */
-static inline void *snd_soc_dai_get_sdw_stream(struct snd_soc_dai *dai,
-                                              int direction)
+static inline void *snd_soc_dai_get_stream(struct snd_soc_dai *dai,
+                                          int direction)
 {
-       if (dai->driver->ops->get_sdw_stream)
-               return dai->driver->ops->get_sdw_stream(dai, direction);
+       if (dai->driver->ops->get_stream)
+               return dai->driver->ops->get_stream(dai, direction);
        else
                return ERR_PTR(-ENOTSUPP);
 }
index 39afa011f0e2750dfbd5eaebf2793031bf900830..a2bb93fb830b4fb9f8bdb22ff40a4046630747c2 100644 (file)
@@ -728,7 +728,7 @@ static int max98373_sdw_set_tdm_slot(struct snd_soc_dai *dai,
 static const struct snd_soc_dai_ops max98373_dai_sdw_ops = {
        .hw_params = max98373_sdw_dai_hw_params,
        .hw_free = max98373_pcm_hw_free,
-       .set_sdw_stream = max98373_set_sdw_stream,
+       .set_stream = max98373_set_sdw_stream,
        .shutdown = max98373_shutdown,
        .set_tdm_slot = max98373_sdw_set_tdm_slot,
 };
index 31daa749c3db4dae5633d8bfc27680e8f9e96dad..a13296edf295cda19ef378015bf6e23674695cb0 100644 (file)
@@ -613,7 +613,7 @@ static const struct snd_soc_component_driver soc_component_sdw_rt1308 = {
 static const struct snd_soc_dai_ops rt1308_aif_dai_ops = {
        .hw_params = rt1308_sdw_hw_params,
        .hw_free        = rt1308_sdw_pcm_hw_free,
-       .set_sdw_stream = rt1308_set_sdw_stream,
+       .set_stream     = rt1308_set_sdw_stream,
        .shutdown       = rt1308_sdw_shutdown,
        .set_tdm_slot   = rt1308_sdw_set_tdm_slot,
 };
index c9868dd096fcde478a18d2c5dd3cdca1da806bfa..2fb6b1edf9331772a235b5e414635e20c0d7021e 100644 (file)
@@ -272,7 +272,7 @@ static int rt5682_sdw_hw_free(struct snd_pcm_substream *substream,
 static struct snd_soc_dai_ops rt5682_sdw_ops = {
        .hw_params      = rt5682_sdw_hw_params,
        .hw_free        = rt5682_sdw_hw_free,
-       .set_sdw_stream = rt5682_set_sdw_stream,
+       .set_stream     = rt5682_set_sdw_stream,
        .shutdown       = rt5682_sdw_shutdown,
 };
 
index 687ac2153666ba8cb3395e0b6b758e857c98767d..80acf0daabf84718de5b085cbb60cd5671a0e71d 100644 (file)
@@ -1005,7 +1005,7 @@ static int rt700_pcm_hw_free(struct snd_pcm_substream *substream,
 static struct snd_soc_dai_ops rt700_ops = {
        .hw_params      = rt700_pcm_hw_params,
        .hw_free        = rt700_pcm_hw_free,
-       .set_sdw_stream = rt700_set_sdw_stream,
+       .set_stream     = rt700_set_sdw_stream,
        .shutdown       = rt700_shutdown,
 };
 
index 93d86f7558e0a983b39547d124df7d02918683bf..9bdcc7872053b1076e6d3ea69ce26cd0dcb280af 100644 (file)
@@ -1059,7 +1059,7 @@ static int rt711_pcm_hw_free(struct snd_pcm_substream *substream,
 static struct snd_soc_dai_ops rt711_ops = {
        .hw_params      = rt711_pcm_hw_params,
        .hw_free        = rt711_pcm_hw_free,
-       .set_sdw_stream = rt711_set_sdw_stream,
+       .set_stream     = rt711_set_sdw_stream,
        .shutdown       = rt711_shutdown,
 };
 
index 532c5303e7ab0d8a3017fbc7ef71bfbaf8d46834..22bdccf6634683e35d4419ec3baa7afaba565869 100644 (file)
@@ -686,7 +686,7 @@ static int rt715_pcm_hw_free(struct snd_pcm_substream *substream,
 static struct snd_soc_dai_ops rt715_ops = {
        .hw_params      = rt715_pcm_hw_params,
        .hw_free        = rt715_pcm_hw_free,
-       .set_sdw_stream = rt715_set_sdw_stream,
+       .set_stream     = rt715_set_sdw_stream,
        .shutdown       = rt715_shutdown,
 };
 
index 601525c77bbaf3c5a98a1481ca7162116592a94a..15b3f47fbfa35682ba7b0961733572a1bb71e52a 100644 (file)
@@ -1026,7 +1026,7 @@ static struct snd_soc_dai_ops wsa881x_dai_ops = {
        .hw_params = wsa881x_hw_params,
        .hw_free = wsa881x_hw_free,
        .mute_stream = wsa881x_digital_mute,
-       .set_sdw_stream = wsa881x_set_sdw_stream,
+       .set_stream = wsa881x_set_sdw_stream,
 };
 
 static struct snd_soc_dai_driver wsa881x_dais[] = {
index 25548555d8d790304a9ce7a384cb460847d85224..f5d8f7951cfc3e49a224f42a4a32ae31b2512f03 100644 (file)
@@ -231,7 +231,7 @@ int sdw_prepare(struct snd_pcm_substream *substream)
        /* Find stream from first CPU DAI */
        dai = asoc_rtd_to_cpu(rtd, 0);
 
-       sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
+       sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
 
        if (IS_ERR(sdw_stream)) {
                dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
@@ -251,7 +251,7 @@ int sdw_trigger(struct snd_pcm_substream *substream, int cmd)
        /* Find stream from first CPU DAI */
        dai = asoc_rtd_to_cpu(rtd, 0);
 
-       sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
+       sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
 
        if (IS_ERR(sdw_stream)) {
                dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
@@ -290,7 +290,7 @@ int sdw_hw_free(struct snd_pcm_substream *substream)
        /* Find stream from first CPU DAI */
        dai = asoc_rtd_to_cpu(rtd, 0);
 
-       sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream);
+       sdw_stream = snd_soc_dai_get_stream(dai, substream->stream);
 
        if (IS_ERR(sdw_stream)) {
                dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
index 153e9b2de0b53719a6037e984631f50b01f54970..6be7a32933ad09a35b1f1fbe145b761ecd44b1f7 100644 (file)
@@ -56,8 +56,8 @@ static int sdm845_slim_snd_hw_params(struct snd_pcm_substream *substream,
        int ret = 0, i;
 
        for_each_rtd_codec_dais(rtd, i, codec_dai) {
-               sruntime = snd_soc_dai_get_sdw_stream(codec_dai,
-                                                     substream->stream);
+               sruntime = snd_soc_dai_get_stream(codec_dai,
+                                                 substream->stream);
                if (sruntime != ERR_PTR(-ENOTSUPP))
                        pdata->sruntime[cpu_dai->id] = sruntime;