Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC/SoundWire: dai: expand 'stream' concept beyond SoundWire

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>

authored by

Pierre-Louis Bossart and committed by
Mark Brown
e8444560 8ddeafb9

+45 -45
+4 -4
drivers/soundwire/intel.c
··· 1129 1129 .hw_free = intel_hw_free, 1130 1130 .trigger = intel_trigger, 1131 1131 .shutdown = intel_shutdown, 1132 - .set_sdw_stream = intel_pcm_set_sdw_stream, 1133 - .get_sdw_stream = intel_get_sdw_stream, 1132 + .set_stream = intel_pcm_set_sdw_stream, 1133 + .get_stream = intel_get_sdw_stream, 1134 1134 }; 1135 1135 1136 1136 static const struct snd_soc_dai_ops intel_pdm_dai_ops = { ··· 1139 1139 .prepare = intel_prepare, 1140 1140 .hw_free = intel_hw_free, 1141 1141 .shutdown = intel_shutdown, 1142 - .set_sdw_stream = intel_pdm_set_sdw_stream, 1143 - .get_sdw_stream = intel_get_sdw_stream, 1142 + .set_stream = intel_pdm_set_sdw_stream, 1143 + .get_stream = intel_get_sdw_stream, 1144 1144 }; 1145 1145 1146 1146 static const struct snd_soc_component_driver dai_component = {
+4 -4
drivers/soundwire/qcom.c
··· 1024 1024 ctrl->sruntime[dai->id] = sruntime; 1025 1025 1026 1026 for_each_rtd_codec_dais(rtd, i, codec_dai) { 1027 - ret = snd_soc_dai_set_sdw_stream(codec_dai, sruntime, 1028 - substream->stream); 1027 + ret = snd_soc_dai_set_stream(codec_dai, sruntime, 1028 + substream->stream); 1029 1029 if (ret < 0 && ret != -ENOTSUPP) { 1030 1030 dev_err(dai->dev, "Failed to set sdw stream on %s\n", 1031 1031 codec_dai->name); ··· 1051 1051 .hw_free = qcom_swrm_hw_free, 1052 1052 .startup = qcom_swrm_startup, 1053 1053 .shutdown = qcom_swrm_shutdown, 1054 - .set_sdw_stream = qcom_swrm_set_sdw_stream, 1055 - .get_sdw_stream = qcom_swrm_get_sdw_stream, 1054 + .set_stream = qcom_swrm_set_sdw_stream, 1055 + .get_stream = qcom_swrm_get_sdw_stream, 1056 1056 }; 1057 1057 1058 1058 static const struct snd_soc_component_driver qcom_swrm_dai_component = {
+2 -2
drivers/soundwire/stream.c
··· 1863 1863 1864 1864 /* Set stream pointer on all DAIs */ 1865 1865 for_each_rtd_dais(rtd, i, dai) { 1866 - ret = snd_soc_dai_set_sdw_stream(dai, sdw_stream, substream->stream); 1866 + ret = snd_soc_dai_set_stream(dai, sdw_stream, substream->stream); 1867 1867 if (ret < 0) { 1868 1868 dev_err(rtd->dev, "failed to set stream pointer on dai %s\n", dai->name); 1869 1869 break; ··· 1934 1934 /* Find stream from first CPU DAI */ 1935 1935 dai = asoc_rtd_to_cpu(rtd, 0); 1936 1936 1937 - sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream); 1937 + sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 1938 1938 1939 1939 if (IS_ERR(sdw_stream)) { 1940 1940 dev_err(rtd->dev, "no stream found for DAI %s\n", dai->name);
+16 -16
include/sound/soc-dai.h
··· 295 295 unsigned int *rx_num, unsigned int *rx_slot); 296 296 int (*set_tristate)(struct snd_soc_dai *dai, int tristate); 297 297 298 - int (*set_sdw_stream)(struct snd_soc_dai *dai, 299 - void *stream, int direction); 300 - void *(*get_sdw_stream)(struct snd_soc_dai *dai, int direction); 298 + int (*set_stream)(struct snd_soc_dai *dai, 299 + void *stream, int direction); 300 + void *(*get_stream)(struct snd_soc_dai *dai, int direction); 301 301 302 302 /* 303 303 * DAI digital mute - optional. ··· 515 515 } 516 516 517 517 /** 518 - * snd_soc_dai_set_sdw_stream() - Configures a DAI for SDW stream operation 518 + * snd_soc_dai_set_stream() - Configures a DAI for stream operation 519 519 * @dai: DAI 520 - * @stream: STREAM 520 + * @stream: STREAM (opaque structure depending on DAI type) 521 521 * @direction: Stream direction(Playback/Capture) 522 - * SoundWire subsystem doesn't have a notion of direction and we reuse 522 + * Some subsystems, such as SoundWire, don't have a notion of direction and we reuse 523 523 * the ASoC stream direction to configure sink/source ports. 524 524 * Playback maps to source ports and Capture for sink ports. 525 525 * 526 526 * This should be invoked with NULL to clear the stream set previously. 527 527 * Returns 0 on success, a negative error code otherwise. 528 528 */ 529 - static inline int snd_soc_dai_set_sdw_stream(struct snd_soc_dai *dai, 530 - void *stream, int direction) 529 + static inline int snd_soc_dai_set_stream(struct snd_soc_dai *dai, 530 + void *stream, int direction) 531 531 { 532 - if (dai->driver->ops->set_sdw_stream) 533 - return dai->driver->ops->set_sdw_stream(dai, stream, direction); 532 + if (dai->driver->ops->set_stream) 533 + return dai->driver->ops->set_stream(dai, stream, direction); 534 534 else 535 535 return -ENOTSUPP; 536 536 } 537 537 538 538 /** 539 - * snd_soc_dai_get_sdw_stream() - Retrieves SDW stream from DAI 539 + * snd_soc_dai_get_stream() - Retrieves stream from DAI 540 540 * @dai: DAI 541 541 * @direction: Stream direction(Playback/Capture) 542 542 * 543 543 * This routine only retrieves that was previously configured 544 - * with snd_soc_dai_get_sdw_stream() 544 + * with snd_soc_dai_get_stream() 545 545 * 546 546 * Returns pointer to stream or an ERR_PTR value, e.g. 547 547 * ERR_PTR(-ENOTSUPP) if callback is not supported; 548 548 */ 549 - static inline void *snd_soc_dai_get_sdw_stream(struct snd_soc_dai *dai, 550 - int direction) 549 + static inline void *snd_soc_dai_get_stream(struct snd_soc_dai *dai, 550 + int direction) 551 551 { 552 - if (dai->driver->ops->get_sdw_stream) 553 - return dai->driver->ops->get_sdw_stream(dai, direction); 552 + if (dai->driver->ops->get_stream) 553 + return dai->driver->ops->get_stream(dai, direction); 554 554 else 555 555 return ERR_PTR(-ENOTSUPP); 556 556 }
+1 -1
sound/soc/codecs/max98373-sdw.c
··· 741 741 static const struct snd_soc_dai_ops max98373_dai_sdw_ops = { 742 742 .hw_params = max98373_sdw_dai_hw_params, 743 743 .hw_free = max98373_pcm_hw_free, 744 - .set_sdw_stream = max98373_set_sdw_stream, 744 + .set_stream = max98373_set_sdw_stream, 745 745 .shutdown = max98373_shutdown, 746 746 .set_tdm_slot = max98373_sdw_set_tdm_slot, 747 747 };
+1 -1
sound/soc/codecs/rt1308-sdw.c
··· 613 613 static const struct snd_soc_dai_ops rt1308_aif_dai_ops = { 614 614 .hw_params = rt1308_sdw_hw_params, 615 615 .hw_free = rt1308_sdw_pcm_hw_free, 616 - .set_sdw_stream = rt1308_set_sdw_stream, 616 + .set_stream = rt1308_set_sdw_stream, 617 617 .shutdown = rt1308_sdw_shutdown, 618 618 .set_tdm_slot = rt1308_sdw_set_tdm_slot, 619 619 };
+1 -1
sound/soc/codecs/rt1316-sdw.c
··· 602 602 static const struct snd_soc_dai_ops rt1316_aif_dai_ops = { 603 603 .hw_params = rt1316_sdw_hw_params, 604 604 .hw_free = rt1316_sdw_pcm_hw_free, 605 - .set_sdw_stream = rt1316_set_sdw_stream, 605 + .set_stream = rt1316_set_sdw_stream, 606 606 .shutdown = rt1316_sdw_shutdown, 607 607 }; 608 608
+1 -1
sound/soc/codecs/rt5682-sdw.c
··· 272 272 static const struct snd_soc_dai_ops rt5682_sdw_ops = { 273 273 .hw_params = rt5682_sdw_hw_params, 274 274 .hw_free = rt5682_sdw_hw_free, 275 - .set_sdw_stream = rt5682_set_sdw_stream, 275 + .set_stream = rt5682_set_sdw_stream, 276 276 .shutdown = rt5682_sdw_shutdown, 277 277 }; 278 278
+1 -1
sound/soc/codecs/rt700.c
··· 1005 1005 static const struct snd_soc_dai_ops rt700_ops = { 1006 1006 .hw_params = rt700_pcm_hw_params, 1007 1007 .hw_free = rt700_pcm_hw_free, 1008 - .set_sdw_stream = rt700_set_sdw_stream, 1008 + .set_stream = rt700_set_sdw_stream, 1009 1009 .shutdown = rt700_shutdown, 1010 1010 }; 1011 1011
+1 -1
sound/soc/codecs/rt711-sdca.c
··· 1358 1358 static const struct snd_soc_dai_ops rt711_sdca_ops = { 1359 1359 .hw_params = rt711_sdca_pcm_hw_params, 1360 1360 .hw_free = rt711_sdca_pcm_hw_free, 1361 - .set_sdw_stream = rt711_sdca_set_sdw_stream, 1361 + .set_stream = rt711_sdca_set_sdw_stream, 1362 1362 .shutdown = rt711_sdca_shutdown, 1363 1363 }; 1364 1364
+1 -1
sound/soc/codecs/rt711.c
··· 1089 1089 static const struct snd_soc_dai_ops rt711_ops = { 1090 1090 .hw_params = rt711_pcm_hw_params, 1091 1091 .hw_free = rt711_pcm_hw_free, 1092 - .set_sdw_stream = rt711_set_sdw_stream, 1092 + .set_stream = rt711_set_sdw_stream, 1093 1093 .shutdown = rt711_shutdown, 1094 1094 }; 1095 1095
+1 -1
sound/soc/codecs/rt715-sdca.c
··· 938 938 static const struct snd_soc_dai_ops rt715_sdca_ops = { 939 939 .hw_params = rt715_sdca_pcm_hw_params, 940 940 .hw_free = rt715_sdca_pcm_hw_free, 941 - .set_sdw_stream = rt715_sdca_set_sdw_stream, 941 + .set_stream = rt715_sdca_set_sdw_stream, 942 942 .shutdown = rt715_sdca_shutdown, 943 943 }; 944 944
+1 -1
sound/soc/codecs/rt715.c
··· 909 909 static const struct snd_soc_dai_ops rt715_ops = { 910 910 .hw_params = rt715_pcm_hw_params, 911 911 .hw_free = rt715_pcm_hw_free, 912 - .set_sdw_stream = rt715_set_sdw_stream, 912 + .set_stream = rt715_set_sdw_stream, 913 913 .shutdown = rt715_shutdown, 914 914 }; 915 915
+1 -1
sound/soc/codecs/sdw-mockup.c
··· 138 138 static const struct snd_soc_dai_ops sdw_mockup_ops = { 139 139 .hw_params = sdw_mockup_pcm_hw_params, 140 140 .hw_free = sdw_mockup_pcm_hw_free, 141 - .set_sdw_stream = sdw_mockup_set_sdw_stream, 141 + .set_stream = sdw_mockup_set_sdw_stream, 142 142 .shutdown = sdw_mockup_shutdown, 143 143 }; 144 144
+1 -1
sound/soc/codecs/wcd938x.c
··· 4287 4287 static const struct snd_soc_dai_ops wcd938x_sdw_dai_ops = { 4288 4288 .hw_params = wcd938x_codec_hw_params, 4289 4289 .hw_free = wcd938x_codec_free, 4290 - .set_sdw_stream = wcd938x_codec_set_sdw_stream, 4290 + .set_stream = wcd938x_codec_set_sdw_stream, 4291 4291 }; 4292 4292 4293 4293 static struct snd_soc_dai_driver wcd938x_dais[] = {
+1 -1
sound/soc/codecs/wsa881x.c
··· 1018 1018 .hw_params = wsa881x_hw_params, 1019 1019 .hw_free = wsa881x_hw_free, 1020 1020 .mute_stream = wsa881x_digital_mute, 1021 - .set_sdw_stream = wsa881x_set_sdw_stream, 1021 + .set_stream = wsa881x_set_sdw_stream, 1022 1022 }; 1023 1023 1024 1024 static struct snd_soc_dai_driver wsa881x_dais[] = {
+3 -3
sound/soc/intel/boards/sof_sdw.c
··· 347 347 /* Find stream from first CPU DAI */ 348 348 dai = asoc_rtd_to_cpu(rtd, 0); 349 349 350 - sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream); 350 + sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 351 351 352 352 if (IS_ERR(sdw_stream)) { 353 353 dev_err(rtd->dev, "no stream found for DAI %s", dai->name); ··· 367 367 /* Find stream from first CPU DAI */ 368 368 dai = asoc_rtd_to_cpu(rtd, 0); 369 369 370 - sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream); 370 + sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 371 371 372 372 if (IS_ERR(sdw_stream)) { 373 373 dev_err(rtd->dev, "no stream found for DAI %s", dai->name); ··· 406 406 /* Find stream from first CPU DAI */ 407 407 dai = asoc_rtd_to_cpu(rtd, 0); 408 408 409 - sdw_stream = snd_soc_dai_get_sdw_stream(dai, substream->stream); 409 + sdw_stream = snd_soc_dai_get_stream(dai, substream->stream); 410 410 411 411 if (IS_ERR(sdw_stream)) { 412 412 dev_err(rtd->dev, "no stream found for DAI %s", dai->name);
+2 -2
sound/soc/qcom/sdm845.c
··· 57 57 int ret = 0, i; 58 58 59 59 for_each_rtd_codec_dais(rtd, i, codec_dai) { 60 - sruntime = snd_soc_dai_get_sdw_stream(codec_dai, 61 - substream->stream); 60 + sruntime = snd_soc_dai_get_stream(codec_dai, 61 + substream->stream); 62 62 if (sruntime != ERR_PTR(-ENOTSUPP)) 63 63 pdata->sruntime[cpu_dai->id] = sruntime; 64 64
+2 -2
sound/soc/qcom/sm8250.c
··· 136 136 case TX_CODEC_DMA_TX_2: 137 137 case TX_CODEC_DMA_TX_3: 138 138 for_each_rtd_codec_dais(rtd, i, codec_dai) { 139 - sruntime = snd_soc_dai_get_sdw_stream(codec_dai, 140 - substream->stream); 139 + sruntime = snd_soc_dai_get_stream(codec_dai, 140 + substream->stream); 141 141 if (sruntime != ERR_PTR(-ENOTSUPP)) 142 142 pdata->sruntime[cpu_dai->id] = sruntime; 143 143 }