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

ASoC: qcom: sdw: fix memory leak

Merge series from Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>:

For some reason we endedup allocating sdw_stream_runtime for every cpu dai,
this has two issues.
1. we never set snd_soc_dai_set_stream for non soundwire dai, which
means there is no way that we can free this, resulting in memory leak
2. startup and shutdown callbacks can be called without
hw_params callback called. This combination results in memory leak
because machine driver sruntime array pointer is only set in hw_params
callback.

All the machine drivers have these memory leaks, so cleanup the mess and
make them use common helpers from sdw.c

This patch series fix the issue, and while we are at it, it also remove
some redundant code from machine drivers.

+120 -282
+4
sound/soc/codecs/rt721-sdca.c
··· 281 281 rt_sdca_index_write(rt721->mbq_regmap, RT721_BOOST_CTRL, 282 282 RT721_BST_4CH_TOP_GATING_CTRL1, 0x002a); 283 283 regmap_write(rt721->regmap, 0x2f58, 0x07); 284 + 285 + regmap_write(rt721->regmap, 0x2f51, 0x00); 286 + rt_sdca_index_write(rt721->mbq_regmap, RT721_HDA_SDCA_FLOAT, 287 + RT721_MISC_CTL, 0x0004); 284 288 } 285 289 286 290 static void rt721_sdca_jack_init(struct rt721_sdca_priv *rt721)
+1
sound/soc/codecs/rt721-sdca.h
··· 137 137 #define RT721_HDA_LEGACY_UAJ_CTL 0x02 138 138 #define RT721_HDA_LEGACY_CTL1 0x05 139 139 #define RT721_HDA_LEGACY_RESET_CTL 0x06 140 + #define RT721_MISC_CTL 0x07 140 141 #define RT721_XU_REL_CTRL 0x0c 141 142 #define RT721_GE_REL_CTRL1 0x0d 142 143 #define RT721_HDA_LEGACY_GPIO_WAKE_EN_CTL 0x0e
+2 -2
sound/soc/fsl/fsl_micfil.c
··· 131 131 .fifos = 8, 132 132 .fifo_depth = 32, 133 133 .dataline = 0xf, 134 - .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_DSD_U32_BE, 134 + .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_DSD_U32_LE, 135 135 .use_edma = true, 136 136 .use_verid = true, 137 137 .volume_sx = false, ··· 823 823 break; 824 824 } 825 825 826 - if (format == SNDRV_PCM_FORMAT_DSD_U32_BE) { 826 + if (format == SNDRV_PCM_FORMAT_DSD_U32_LE) { 827 827 micfil->dec_bypass = true; 828 828 /* 829 829 * According to equation 29 in RM:
+5 -6
sound/soc/fsl/fsl_sai.c
··· 353 353 break; 354 354 case SND_SOC_DAIFMT_PDM: 355 355 val_cr2 |= FSL_SAI_CR2_BCP; 356 - val_cr4 &= ~FSL_SAI_CR4_MF; 357 356 sai->is_pdm_mode = true; 358 357 break; 359 358 case SND_SOC_DAIFMT_RIGHT_J: ··· 637 638 val_cr5 |= FSL_SAI_CR5_WNW(slot_width); 638 639 val_cr5 |= FSL_SAI_CR5_W0W(slot_width); 639 640 640 - if (sai->is_lsb_first || sai->is_pdm_mode) 641 + if (sai->is_lsb_first) 641 642 val_cr5 |= FSL_SAI_CR5_FBT(0); 642 643 else 643 644 val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); ··· 652 653 val_cr4 |= FSL_SAI_CR4_CHMOD; 653 654 654 655 /* 655 - * For SAI provider mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will 656 - * generate bclk and frame clock for Tx(Rx), we should set RCR4(TCR4), 657 - * RCR5(TCR5) for playback(capture), or there will be sync error. 656 + * When Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will provide bclk and 657 + * frame clock for Tx(Rx). We should set RCR4(TCR4), RCR5(TCR5) 658 + * for playback(capture), or there will be sync error. 658 659 */ 659 660 660 - if (!sai->is_consumer_mode[tx] && fsl_sai_dir_is_synced(sai, adir)) { 661 + if (fsl_sai_dir_is_synced(sai, adir)) { 661 662 regmap_update_bits(sai->regmap, FSL_SAI_xCR4(!tx, ofs), 662 663 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK | 663 664 FSL_SAI_CR4_CHMOD_MASK,
+3
sound/soc/intel/avs/pcm.c
··· 651 651 652 652 data = snd_soc_dai_get_dma_data(dai, substream); 653 653 654 + disable_work_sync(&data->period_elapsed_work); 654 655 snd_hdac_ext_stream_release(data->host_stream, HDAC_EXT_STREAM_TYPE_HOST); 655 656 avs_dai_shutdown(substream, dai); 656 657 } ··· 755 754 data = snd_soc_dai_get_dma_data(dai, substream); 756 755 host_stream = data->host_stream; 757 756 757 + if (runtime->state == SNDRV_PCM_STATE_XRUN) 758 + hdac_stream(host_stream)->prepared = false; 758 759 if (hdac_stream(host_stream)->prepared) 759 760 return 0; 760 761
+10 -8
sound/soc/intel/avs/probes.c
··· 14 14 #include "debug.h" 15 15 #include "messages.h" 16 16 17 - static int avs_dsp_init_probe(struct avs_dev *adev, union avs_connector_node_id node_id, 18 - size_t buffer_size) 17 + static int avs_dsp_init_probe(struct avs_dev *adev, struct snd_compr_params *params, int bps, 18 + union avs_connector_node_id node_id, size_t buffer_size) 19 19 { 20 20 struct avs_probe_cfg cfg = {{0}}; 21 21 struct avs_module_entry mentry; ··· 27 27 return ret; 28 28 29 29 /* 30 - * Probe module uses no cycles, audio data format and input and output 31 - * frame sizes are unused. It is also not owned by any pipeline. 30 + * Probe module uses no cycles, input and output frame sizes are unused. 31 + * It is also not owned by any pipeline. 32 32 */ 33 33 cfg.base.ibs = 1; 34 34 /* BSS module descriptor is always segment of index=2. */ 35 35 cfg.base.is_pages = mentry.segments[2].flags.length; 36 + cfg.base.audio_fmt.sampling_freq = params->codec.sample_rate; 37 + cfg.base.audio_fmt.bit_depth = bps; 38 + cfg.base.audio_fmt.num_channels = params->codec.ch_out; 39 + cfg.base.audio_fmt.valid_bit_depth = bps; 36 40 cfg.gtw_cfg.node_id = node_id; 37 41 cfg.gtw_cfg.dma_buffer_size = buffer_size; 38 42 ··· 132 128 struct hdac_ext_stream *host_stream = avs_compr_get_host_stream(cstream); 133 129 struct snd_compr_runtime *rtd = cstream->runtime; 134 130 struct avs_dev *adev = to_avs_dev(dai->dev); 135 - /* compr params do not store bit depth, default to S32_LE. */ 136 - snd_pcm_format_t format = SNDRV_PCM_FORMAT_S32_LE; 137 131 unsigned int format_val; 138 132 int bps, ret; 139 133 ··· 144 142 ret = snd_compr_malloc_pages(cstream, rtd->buffer_size); 145 143 if (ret < 0) 146 144 return ret; 147 - bps = snd_pcm_format_physical_width(format); 145 + bps = snd_pcm_format_physical_width(params->codec.format); 148 146 if (bps < 0) 149 147 return bps; 150 148 format_val = snd_hdac_stream_format(params->codec.ch_out, bps, params->codec.sample_rate); ··· 168 166 node_id.vindex = hdac_stream(host_stream)->stream_tag - 1; 169 167 node_id.dma_type = AVS_DMA_HDA_HOST_INPUT; 170 168 171 - ret = avs_dsp_init_probe(adev, node_id, rtd->dma_bytes); 169 + ret = avs_dsp_init_probe(adev, params, bps, node_id, rtd->dma_bytes); 172 170 if (ret < 0) { 173 171 dev_err(dai->dev, "probe init failed: %d\n", ret); 174 172 avs_dsp_enable_d0ix(adev);
-1
sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
··· 3174 3174 3175 3175 static void mt8195_afe_pcm_dev_remove(struct platform_device *pdev) 3176 3176 { 3177 - pm_runtime_disable(&pdev->dev); 3178 3177 if (!pm_runtime_status_suspended(&pdev->dev)) 3179 3178 mt8195_afe_runtime_suspend(&pdev->dev); 3180 3179 }
-1
sound/soc/mediatek/mt8365/mt8365-afe-pcm.c
··· 2238 2238 2239 2239 mt8365_afe_disable_top_cg(afe, MT8365_TOP_CG_AFE); 2240 2240 2241 - pm_runtime_disable(&pdev->dev); 2242 2241 if (!pm_runtime_status_suspended(&pdev->dev)) 2243 2242 mt8365_afe_runtime_suspend(&pdev->dev); 2244 2243 }
+3 -64
sound/soc/qcom/sc7280.c
··· 31 31 32 32 struct sc7280_snd_data { 33 33 struct snd_soc_card card; 34 - struct sdw_stream_runtime *sruntime[LPASS_MAX_PORTS]; 35 34 u32 pri_mi2s_clk_count; 36 35 struct snd_soc_jack hs_jack; 37 36 struct snd_soc_jack hdmi_jack; ··· 206 207 { 207 208 struct snd_pcm_runtime *runtime = substream->runtime; 208 209 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 209 - struct snd_soc_dai *codec_dai; 210 - const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 211 - struct sc7280_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card); 212 - struct sdw_stream_runtime *sruntime; 213 - int i; 214 210 215 211 if (!rtd->dai_link->no_pcm) { 216 212 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); 217 213 snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_RATE, 48000, 48000); 218 - } 219 - 220 - switch (cpu_dai->id) { 221 - case LPASS_CDC_DMA_TX3: 222 - case LPASS_CDC_DMA_RX0: 223 - case RX_CODEC_DMA_RX_0: 224 - case SECONDARY_MI2S_RX: 225 - case TX_CODEC_DMA_TX_3: 226 - case VA_CODEC_DMA_TX_0: 227 - for_each_rtd_codec_dais(rtd, i, codec_dai) { 228 - sruntime = snd_soc_dai_get_stream(codec_dai, substream->stream); 229 - if (sruntime != ERR_PTR(-ENOTSUPP)) 230 - pdata->sruntime[cpu_dai->id] = sruntime; 231 - } 232 - break; 233 214 } 234 215 235 216 return 0; ··· 220 241 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 221 242 const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 222 243 struct sc7280_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 223 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 224 - int ret; 225 244 226 - if (!sruntime) 227 - return 0; 228 - 229 - if (data->stream_prepared[cpu_dai->id]) { 230 - sdw_disable_stream(sruntime); 231 - sdw_deprepare_stream(sruntime); 232 - data->stream_prepared[cpu_dai->id] = false; 233 - } 234 - 235 - ret = sdw_prepare_stream(sruntime); 236 - if (ret) 237 - return ret; 238 - 239 - ret = sdw_enable_stream(sruntime); 240 - if (ret) { 241 - sdw_deprepare_stream(sruntime); 242 - return ret; 243 - } 244 - data->stream_prepared[cpu_dai->id] = true; 245 - 246 - return ret; 245 + return qcom_snd_sdw_prepare(substream, &data->stream_prepared[cpu_dai->id]); 247 246 } 248 247 249 248 static int sc7280_snd_prepare(struct snd_pcm_substream *substream) ··· 248 291 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 249 292 struct sc7280_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 250 293 const struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 251 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 252 294 253 - switch (cpu_dai->id) { 254 - case LPASS_CDC_DMA_RX0: 255 - case LPASS_CDC_DMA_TX3: 256 - case RX_CODEC_DMA_RX_0: 257 - case TX_CODEC_DMA_TX_3: 258 - case VA_CODEC_DMA_TX_0: 259 - if (sruntime && data->stream_prepared[cpu_dai->id]) { 260 - sdw_disable_stream(sruntime); 261 - sdw_deprepare_stream(sruntime); 262 - data->stream_prepared[cpu_dai->id] = false; 263 - } 264 - break; 265 - default: 266 - break; 267 - } 268 - return 0; 295 + return qcom_snd_sdw_hw_free(substream, &data->stream_prepared[cpu_dai->id]); 269 296 } 270 297 271 298 static void sc7280_snd_shutdown(struct snd_pcm_substream *substream) ··· 258 317 struct snd_soc_card *card = rtd->card; 259 318 struct sc7280_snd_data *data = snd_soc_card_get_drvdata(card); 260 319 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 261 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 262 320 263 321 switch (cpu_dai->id) { 264 322 case MI2S_PRIMARY: ··· 276 336 break; 277 337 } 278 338 279 - data->sruntime[cpu_dai->id] = NULL; 280 - sdw_release_stream(sruntime); 339 + qcom_snd_sdw_shutdown(substream); 281 340 } 282 341 283 342 static int sc7280_snd_startup(struct snd_pcm_substream *substream)
+3 -30
sound/soc/qcom/sc8280xp.c
··· 18 18 struct sc8280xp_snd_data { 19 19 bool stream_prepared[AFE_PORT_MAX]; 20 20 struct snd_soc_card *card; 21 - struct sdw_stream_runtime *sruntime[AFE_PORT_MAX]; 22 21 struct snd_soc_jack jack; 23 22 struct snd_soc_jack dp_jack[8]; 24 23 bool jack_setup; ··· 67 68 return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup); 68 69 } 69 70 70 - static void sc8280xp_snd_shutdown(struct snd_pcm_substream *substream) 71 - { 72 - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 73 - struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 74 - struct sc8280xp_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card); 75 - struct sdw_stream_runtime *sruntime = pdata->sruntime[cpu_dai->id]; 76 - 77 - pdata->sruntime[cpu_dai->id] = NULL; 78 - sdw_release_stream(sruntime); 79 - } 80 - 81 71 static int sc8280xp_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 82 72 struct snd_pcm_hw_params *params) 83 73 { ··· 96 108 return 0; 97 109 } 98 110 99 - static int sc8280xp_snd_hw_params(struct snd_pcm_substream *substream, 100 - struct snd_pcm_hw_params *params) 101 - { 102 - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 103 - struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 104 - struct sc8280xp_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card); 105 - 106 - return qcom_snd_sdw_hw_params(substream, params, &pdata->sruntime[cpu_dai->id]); 107 - } 108 - 109 111 static int sc8280xp_snd_prepare(struct snd_pcm_substream *substream) 110 112 { 111 113 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 112 114 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 113 115 struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 114 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 115 116 116 - return qcom_snd_sdw_prepare(substream, sruntime, 117 - &data->stream_prepared[cpu_dai->id]); 117 + return qcom_snd_sdw_prepare(substream, &data->stream_prepared[cpu_dai->id]); 118 118 } 119 119 120 120 static int sc8280xp_snd_hw_free(struct snd_pcm_substream *substream) ··· 110 134 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 111 135 struct sc8280xp_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 112 136 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 113 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 114 137 115 - return qcom_snd_sdw_hw_free(substream, sruntime, 116 - &data->stream_prepared[cpu_dai->id]); 138 + return qcom_snd_sdw_hw_free(substream, &data->stream_prepared[cpu_dai->id]); 117 139 } 118 140 119 141 static const struct snd_soc_ops sc8280xp_be_ops = { 120 142 .startup = qcom_snd_sdw_startup, 121 - .shutdown = sc8280xp_snd_shutdown, 122 - .hw_params = sc8280xp_snd_hw_params, 143 + .shutdown = qcom_snd_sdw_shutdown, 123 144 .hw_free = sc8280xp_snd_hw_free, 124 145 .prepare = sc8280xp_snd_prepare, 125 146 };
+3 -50
sound/soc/qcom/sdm845.c
··· 40 40 uint32_t pri_mi2s_clk_count; 41 41 uint32_t sec_mi2s_clk_count; 42 42 uint32_t quat_tdm_clk_count; 43 - struct sdw_stream_runtime *sruntime[AFE_PORT_MAX]; 44 43 }; 45 44 46 45 static struct snd_soc_jack_pin sdm845_jack_pins[] = { ··· 61 62 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 62 63 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 63 64 struct snd_soc_dai *codec_dai; 64 - struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card); 65 65 u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS]; 66 - struct sdw_stream_runtime *sruntime; 67 66 u32 rx_ch_cnt = 0, tx_ch_cnt = 0; 68 67 int ret = 0, i; 69 68 70 69 for_each_rtd_codec_dais(rtd, i, codec_dai) { 71 - sruntime = snd_soc_dai_get_stream(codec_dai, 72 - substream->stream); 73 - if (sruntime != ERR_PTR(-ENOTSUPP)) 74 - pdata->sruntime[cpu_dai->id] = sruntime; 75 - 76 70 ret = snd_soc_dai_get_channel_map(codec_dai, 77 71 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch); 78 72 ··· 422 430 struct snd_soc_card *card = rtd->card; 423 431 struct sdm845_snd_data *data = snd_soc_card_get_drvdata(card); 424 432 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 425 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 426 433 427 434 switch (cpu_dai->id) { 428 435 case PRIMARY_MI2S_RX: ··· 462 471 break; 463 472 } 464 473 465 - data->sruntime[cpu_dai->id] = NULL; 466 - sdw_release_stream(sruntime); 474 + qcom_snd_sdw_shutdown(substream); 467 475 } 468 476 469 477 static int sdm845_snd_prepare(struct snd_pcm_substream *substream) ··· 470 480 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 471 481 struct sdm845_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 472 482 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 473 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 474 - int ret; 475 483 476 - if (!sruntime) 477 - return 0; 478 - 479 - if (data->stream_prepared[cpu_dai->id]) { 480 - sdw_disable_stream(sruntime); 481 - sdw_deprepare_stream(sruntime); 482 - data->stream_prepared[cpu_dai->id] = false; 483 - } 484 - 485 - ret = sdw_prepare_stream(sruntime); 486 - if (ret) 487 - return ret; 488 - 489 - /** 490 - * NOTE: there is a strict hw requirement about the ordering of port 491 - * enables and actual WSA881x PA enable. PA enable should only happen 492 - * after soundwire ports are enabled if not DC on the line is 493 - * accumulated resulting in Click/Pop Noise 494 - * PA enable/mute are handled as part of codec DAPM and digital mute. 495 - */ 496 - 497 - ret = sdw_enable_stream(sruntime); 498 - if (ret) { 499 - sdw_deprepare_stream(sruntime); 500 - return ret; 501 - } 502 - data->stream_prepared[cpu_dai->id] = true; 503 - 504 - return ret; 484 + return qcom_snd_sdw_prepare(substream, &data->stream_prepared[cpu_dai->id]); 505 485 } 506 486 507 487 static int sdm845_snd_hw_free(struct snd_pcm_substream *substream) ··· 479 519 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 480 520 struct sdm845_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 481 521 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 482 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 483 522 484 - if (sruntime && data->stream_prepared[cpu_dai->id]) { 485 - sdw_disable_stream(sruntime); 486 - sdw_deprepare_stream(sruntime); 487 - data->stream_prepared[cpu_dai->id] = false; 488 - } 489 - 490 - return 0; 523 + return qcom_snd_sdw_hw_free(substream, &data->stream_prepared[cpu_dai->id]); 491 524 } 492 525 493 526 static const struct snd_soc_ops sdm845_be_ops = {
+78 -54
sound/soc/qcom/sdw.c
··· 2 2 // Copyright (c) 2018-2023, Linaro Limited. 3 3 // Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 4 5 + #include <dt-bindings/sound/qcom,lpass.h> 5 6 #include <dt-bindings/sound/qcom,q6afe.h> 6 7 #include <linux/module.h> 7 8 #include <sound/soc.h> 8 9 #include "sdw.h" 10 + 11 + static bool qcom_snd_is_sdw_dai(int id) 12 + { 13 + switch (id) { 14 + case WSA_CODEC_DMA_RX_0: 15 + case WSA_CODEC_DMA_TX_0: 16 + case WSA_CODEC_DMA_RX_1: 17 + case WSA_CODEC_DMA_TX_1: 18 + case WSA_CODEC_DMA_TX_2: 19 + case RX_CODEC_DMA_RX_0: 20 + case TX_CODEC_DMA_TX_0: 21 + case RX_CODEC_DMA_RX_1: 22 + case TX_CODEC_DMA_TX_1: 23 + case RX_CODEC_DMA_RX_2: 24 + case TX_CODEC_DMA_TX_2: 25 + case RX_CODEC_DMA_RX_3: 26 + case TX_CODEC_DMA_TX_3: 27 + case RX_CODEC_DMA_RX_4: 28 + case TX_CODEC_DMA_TX_4: 29 + case RX_CODEC_DMA_RX_5: 30 + case TX_CODEC_DMA_TX_5: 31 + case RX_CODEC_DMA_RX_6: 32 + case RX_CODEC_DMA_RX_7: 33 + case SLIMBUS_0_RX...SLIMBUS_6_TX: 34 + return true; 35 + default: 36 + break; 37 + } 38 + 39 + /* DSP Bypass usecase, cpu dai index overlaps with DSP dai ids, 40 + * DO NOT MERGE into top switch case */ 41 + switch (id) { 42 + case LPASS_CDC_DMA_TX3: 43 + case LPASS_CDC_DMA_RX0: 44 + return true; 45 + default: 46 + break; 47 + } 48 + 49 + return false; 50 + } 9 51 10 52 /** 11 53 * qcom_snd_sdw_startup() - Helper to start Soundwire stream for SoC audio card ··· 70 28 struct snd_soc_dai *codec_dai; 71 29 u32 rx_ch_cnt = 0, tx_ch_cnt = 0; 72 30 int ret, i, j; 31 + 32 + if (!qcom_snd_is_sdw_dai(cpu_dai->id)) 33 + return 0; 73 34 74 35 sruntime = sdw_alloc_stream(cpu_dai->name, SDW_STREAM_PCM); 75 36 if (!sruntime) ··· 124 79 EXPORT_SYMBOL_GPL(qcom_snd_sdw_startup); 125 80 126 81 int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, 127 - struct sdw_stream_runtime *sruntime, 128 82 bool *stream_prepared) 129 83 { 130 84 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 131 85 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 86 + struct sdw_stream_runtime *sruntime; 132 87 int ret; 133 88 134 - if (!sruntime) 89 + 90 + if (!qcom_snd_is_sdw_dai(cpu_dai->id)) 135 91 return 0; 136 92 137 - switch (cpu_dai->id) { 138 - case WSA_CODEC_DMA_RX_0: 139 - case WSA_CODEC_DMA_RX_1: 140 - case RX_CODEC_DMA_RX_0: 141 - case RX_CODEC_DMA_RX_1: 142 - case TX_CODEC_DMA_TX_0: 143 - case TX_CODEC_DMA_TX_1: 144 - case TX_CODEC_DMA_TX_2: 145 - case TX_CODEC_DMA_TX_3: 146 - break; 147 - default: 93 + sruntime = qcom_snd_sdw_get_stream(substream); 94 + if (!sruntime) 148 95 return 0; 149 - } 150 96 151 97 if (*stream_prepared) 152 98 return 0; ··· 165 129 } 166 130 EXPORT_SYMBOL_GPL(qcom_snd_sdw_prepare); 167 131 168 - int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, 169 - struct snd_pcm_hw_params *params, 170 - struct sdw_stream_runtime **psruntime) 132 + struct sdw_stream_runtime *qcom_snd_sdw_get_stream(struct snd_pcm_substream *substream) 171 133 { 172 134 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 173 135 struct snd_soc_dai *codec_dai; ··· 173 139 struct sdw_stream_runtime *sruntime; 174 140 int i; 175 141 176 - switch (cpu_dai->id) { 177 - case WSA_CODEC_DMA_RX_0: 178 - case RX_CODEC_DMA_RX_0: 179 - case RX_CODEC_DMA_RX_1: 180 - case TX_CODEC_DMA_TX_0: 181 - case TX_CODEC_DMA_TX_1: 182 - case TX_CODEC_DMA_TX_2: 183 - case TX_CODEC_DMA_TX_3: 184 - for_each_rtd_codec_dais(rtd, i, codec_dai) { 185 - sruntime = snd_soc_dai_get_stream(codec_dai, substream->stream); 186 - if (sruntime != ERR_PTR(-ENOTSUPP)) 187 - *psruntime = sruntime; 188 - } 189 - break; 142 + if (!qcom_snd_is_sdw_dai(cpu_dai->id)) 143 + return NULL; 144 + 145 + for_each_rtd_codec_dais(rtd, i, codec_dai) { 146 + sruntime = snd_soc_dai_get_stream(codec_dai, substream->stream); 147 + if (sruntime != ERR_PTR(-ENOTSUPP)) 148 + return sruntime; 190 149 } 191 - 192 - return 0; 193 - 150 + return NULL; 194 151 } 195 - EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_params); 152 + EXPORT_SYMBOL_GPL(qcom_snd_sdw_get_stream); 196 153 197 - int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream, 198 - struct sdw_stream_runtime *sruntime, bool *stream_prepared) 154 + void qcom_snd_sdw_shutdown(struct snd_pcm_substream *substream) 155 + { 156 + struct sdw_stream_runtime *sruntime = qcom_snd_sdw_get_stream(substream); 157 + 158 + sdw_release_stream(sruntime); 159 + } 160 + EXPORT_SYMBOL_GPL(qcom_snd_sdw_shutdown); 161 + 162 + int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream, bool *stream_prepared) 199 163 { 200 164 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 201 165 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 166 + struct sdw_stream_runtime *sruntime; 202 167 203 - switch (cpu_dai->id) { 204 - case WSA_CODEC_DMA_RX_0: 205 - case WSA_CODEC_DMA_RX_1: 206 - case RX_CODEC_DMA_RX_0: 207 - case RX_CODEC_DMA_RX_1: 208 - case TX_CODEC_DMA_TX_0: 209 - case TX_CODEC_DMA_TX_1: 210 - case TX_CODEC_DMA_TX_2: 211 - case TX_CODEC_DMA_TX_3: 212 - if (sruntime && *stream_prepared) { 213 - sdw_disable_stream(sruntime); 214 - sdw_deprepare_stream(sruntime); 215 - *stream_prepared = false; 216 - } 217 - break; 218 - default: 219 - break; 168 + if (!qcom_snd_is_sdw_dai(cpu_dai->id)) 169 + return 0; 170 + 171 + sruntime = qcom_snd_sdw_get_stream(substream); 172 + if (sruntime && *stream_prepared) { 173 + sdw_disable_stream(sruntime); 174 + sdw_deprepare_stream(sruntime); 175 + *stream_prepared = false; 220 176 } 221 177 222 178 return 0;
+2 -5
sound/soc/qcom/sdw.h
··· 7 7 #include <linux/soundwire/sdw.h> 8 8 9 9 int qcom_snd_sdw_startup(struct snd_pcm_substream *substream); 10 + void qcom_snd_sdw_shutdown(struct snd_pcm_substream *substream); 10 11 int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, 11 - struct sdw_stream_runtime *runtime, 12 12 bool *stream_prepared); 13 - int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, 14 - struct snd_pcm_hw_params *params, 15 - struct sdw_stream_runtime **psruntime); 13 + struct sdw_stream_runtime *qcom_snd_sdw_get_stream(struct snd_pcm_substream *stream); 16 14 int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream, 17 - struct sdw_stream_runtime *sruntime, 18 15 bool *stream_prepared); 19 16 #endif
+3 -30
sound/soc/qcom/sm8250.c
··· 21 21 struct sm8250_snd_data { 22 22 bool stream_prepared[AFE_PORT_MAX]; 23 23 struct snd_soc_card *card; 24 - struct sdw_stream_runtime *sruntime[AFE_PORT_MAX]; 25 24 struct snd_soc_jack jack; 26 25 struct snd_soc_jack usb_offload_jack; 27 26 bool usb_offload_jack_setup; ··· 111 112 return qcom_snd_sdw_startup(substream); 112 113 } 113 114 114 - static void sm8250_snd_shutdown(struct snd_pcm_substream *substream) 115 - { 116 - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 117 - struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 118 - struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 119 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 120 - 121 - data->sruntime[cpu_dai->id] = NULL; 122 - sdw_release_stream(sruntime); 123 - } 124 - 125 - static int sm8250_snd_hw_params(struct snd_pcm_substream *substream, 126 - struct snd_pcm_hw_params *params) 127 - { 128 - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 129 - struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 130 - struct sm8250_snd_data *pdata = snd_soc_card_get_drvdata(rtd->card); 131 - 132 - return qcom_snd_sdw_hw_params(substream, params, &pdata->sruntime[cpu_dai->id]); 133 - } 134 - 135 115 static int sm8250_snd_prepare(struct snd_pcm_substream *substream) 136 116 { 137 117 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 138 118 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 139 119 struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 140 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 141 120 142 - return qcom_snd_sdw_prepare(substream, sruntime, 143 - &data->stream_prepared[cpu_dai->id]); 121 + return qcom_snd_sdw_prepare(substream, &data->stream_prepared[cpu_dai->id]); 144 122 } 145 123 146 124 static int sm8250_snd_hw_free(struct snd_pcm_substream *substream) ··· 125 149 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 126 150 struct sm8250_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 127 151 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 128 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 129 152 130 - return qcom_snd_sdw_hw_free(substream, sruntime, 131 - &data->stream_prepared[cpu_dai->id]); 153 + return qcom_snd_sdw_hw_free(substream, &data->stream_prepared[cpu_dai->id]); 132 154 } 133 155 134 156 static const struct snd_soc_ops sm8250_be_ops = { 135 157 .startup = sm8250_snd_startup, 136 - .shutdown = sm8250_snd_shutdown, 137 - .hw_params = sm8250_snd_hw_params, 158 + .shutdown = qcom_snd_sdw_shutdown, 138 159 .hw_free = sm8250_snd_hw_free, 139 160 .prepare = sm8250_snd_prepare, 140 161 };
+3 -30
sound/soc/qcom/x1e80100.c
··· 18 18 struct x1e80100_snd_data { 19 19 bool stream_prepared[AFE_PORT_MAX]; 20 20 struct snd_soc_card *card; 21 - struct sdw_stream_runtime *sruntime[AFE_PORT_MAX]; 22 21 struct snd_soc_jack jack; 23 22 struct snd_soc_jack dp_jack[8]; 24 23 bool jack_setup; ··· 49 50 return qcom_snd_wcd_jack_setup(rtd, &data->jack, &data->jack_setup); 50 51 } 51 52 52 - static void x1e80100_snd_shutdown(struct snd_pcm_substream *substream) 53 - { 54 - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 55 - struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 56 - struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 57 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 58 - 59 - data->sruntime[cpu_dai->id] = NULL; 60 - sdw_release_stream(sruntime); 61 - } 62 - 63 53 static int x1e80100_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, 64 54 struct snd_pcm_hw_params *params) 65 55 { ··· 71 83 } 72 84 73 85 return 0; 74 - } 75 - 76 - static int x1e80100_snd_hw_params(struct snd_pcm_substream *substream, 77 - struct snd_pcm_hw_params *params) 78 - { 79 - struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 80 - struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 81 - struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 82 - 83 - return qcom_snd_sdw_hw_params(substream, params, &data->sruntime[cpu_dai->id]); 84 86 } 85 87 86 88 static int x1e80100_snd_hw_map_channels(unsigned int *ch_map, int num) ··· 106 128 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 107 129 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 108 130 struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 109 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 110 131 unsigned int channels = substream->runtime->channels; 111 132 unsigned int rx_slot[4]; 112 133 int ret; ··· 126 149 break; 127 150 } 128 151 129 - return qcom_snd_sdw_prepare(substream, sruntime, 130 - &data->stream_prepared[cpu_dai->id]); 152 + return qcom_snd_sdw_prepare(substream, &data->stream_prepared[cpu_dai->id]); 131 153 } 132 154 133 155 static int x1e80100_snd_hw_free(struct snd_pcm_substream *substream) ··· 134 158 struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); 135 159 struct x1e80100_snd_data *data = snd_soc_card_get_drvdata(rtd->card); 136 160 struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); 137 - struct sdw_stream_runtime *sruntime = data->sruntime[cpu_dai->id]; 138 161 139 - return qcom_snd_sdw_hw_free(substream, sruntime, 140 - &data->stream_prepared[cpu_dai->id]); 162 + return qcom_snd_sdw_hw_free(substream, &data->stream_prepared[cpu_dai->id]); 141 163 } 142 164 143 165 static const struct snd_soc_ops x1e80100_be_ops = { 144 166 .startup = qcom_snd_sdw_startup, 145 - .shutdown = x1e80100_snd_shutdown, 146 - .hw_params = x1e80100_snd_hw_params, 167 + .shutdown = qcom_snd_sdw_shutdown, 147 168 .hw_free = x1e80100_snd_hw_free, 148 169 .prepare = x1e80100_snd_prepare, 149 170 };
-1
sound/soc/sdw_utils/soc_sdw_utils.c
··· 691 691 { 692 692 .direction = {true, false}, 693 693 .dai_name = "cs42l43-dp6", 694 - .component_name = "cs42l43", 695 694 .dai_type = SOC_SDW_DAI_TYPE_AMP, 696 695 .dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID}, 697 696 .init = asoc_sdw_cs42l43_spk_init,