1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2018-2023, Linaro Limited.
3 // Copyright (c) 2018, The Linux Foundation. All rights reserved.
5 #include <dt-bindings/sound/qcom,q6afe.h>
6 #include <linux/module.h>
11 * qcom_snd_sdw_startup() - Helper to start Soundwire stream for SoC audio card
12 * @substream: The PCM substream from audio, as passed to snd_soc_ops->startup()
14 * Helper for the SoC audio card (snd_soc_ops->startup()) to allocate and set
15 * Soundwire stream runtime to each codec DAI.
17 * The shutdown() callback should call sdw_release_stream() on the same
22 int qcom_snd_sdw_startup(struct snd_pcm_substream
*substream
)
24 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
25 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
26 struct sdw_stream_runtime
*sruntime
;
27 struct snd_soc_dai
*codec_dai
;
30 sruntime
= sdw_alloc_stream(cpu_dai
->name
);
34 for_each_rtd_codec_dais(rtd
, i
, codec_dai
) {
35 ret
= snd_soc_dai_set_stream(codec_dai
, sruntime
,
37 if (ret
< 0 && ret
!= -ENOTSUPP
) {
38 dev_err(rtd
->dev
, "Failed to set sdw stream on %s\n",
47 sdw_release_stream(sruntime
);
51 EXPORT_SYMBOL_GPL(qcom_snd_sdw_startup
);
53 int qcom_snd_sdw_prepare(struct snd_pcm_substream
*substream
,
54 struct sdw_stream_runtime
*sruntime
,
55 bool *stream_prepared
)
57 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
58 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
64 switch (cpu_dai
->id
) {
65 case WSA_CODEC_DMA_RX_0
:
66 case WSA_CODEC_DMA_RX_1
:
67 case RX_CODEC_DMA_RX_0
:
68 case RX_CODEC_DMA_RX_1
:
69 case TX_CODEC_DMA_TX_0
:
70 case TX_CODEC_DMA_TX_1
:
71 case TX_CODEC_DMA_TX_2
:
72 case TX_CODEC_DMA_TX_3
:
81 ret
= sdw_prepare_stream(sruntime
);
86 * NOTE: there is a strict hw requirement about the ordering of port
87 * enables and actual WSA881x PA enable. PA enable should only happen
88 * after soundwire ports are enabled if not DC on the line is
89 * accumulated resulting in Click/Pop Noise
90 * PA enable/mute are handled as part of codec DAPM and digital mute.
93 ret
= sdw_enable_stream(sruntime
);
95 sdw_deprepare_stream(sruntime
);
98 *stream_prepared
= true;
102 EXPORT_SYMBOL_GPL(qcom_snd_sdw_prepare
);
104 int qcom_snd_sdw_hw_params(struct snd_pcm_substream
*substream
,
105 struct snd_pcm_hw_params
*params
,
106 struct sdw_stream_runtime
**psruntime
)
108 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
109 struct snd_soc_dai
*codec_dai
;
110 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
111 struct sdw_stream_runtime
*sruntime
;
114 switch (cpu_dai
->id
) {
115 case WSA_CODEC_DMA_RX_0
:
116 case RX_CODEC_DMA_RX_0
:
117 case RX_CODEC_DMA_RX_1
:
118 case TX_CODEC_DMA_TX_0
:
119 case TX_CODEC_DMA_TX_1
:
120 case TX_CODEC_DMA_TX_2
:
121 case TX_CODEC_DMA_TX_3
:
122 for_each_rtd_codec_dais(rtd
, i
, codec_dai
) {
123 sruntime
= snd_soc_dai_get_stream(codec_dai
, substream
->stream
);
124 if (sruntime
!= ERR_PTR(-ENOTSUPP
))
125 *psruntime
= sruntime
;
133 EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_params
);
135 int qcom_snd_sdw_hw_free(struct snd_pcm_substream
*substream
,
136 struct sdw_stream_runtime
*sruntime
, bool *stream_prepared
)
138 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
139 struct snd_soc_dai
*cpu_dai
= snd_soc_rtd_to_cpu(rtd
, 0);
141 switch (cpu_dai
->id
) {
142 case WSA_CODEC_DMA_RX_0
:
143 case WSA_CODEC_DMA_RX_1
:
144 case RX_CODEC_DMA_RX_0
:
145 case RX_CODEC_DMA_RX_1
:
146 case TX_CODEC_DMA_TX_0
:
147 case TX_CODEC_DMA_TX_1
:
148 case TX_CODEC_DMA_TX_2
:
149 case TX_CODEC_DMA_TX_3
:
150 if (sruntime
&& *stream_prepared
) {
151 sdw_disable_stream(sruntime
);
152 sdw_deprepare_stream(sruntime
);
153 *stream_prepared
= false;
162 EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_free
);
163 MODULE_DESCRIPTION("Qualcomm ASoC SoundWire helper functions");
164 MODULE_LICENSE("GPL");