• Home
  • Raw
  • Download

Lines Matching +full:current +full:- +full:num +full:- +full:sinks

1 // SPDX-License-Identifier: GPL-2.0+
3 // soc-pcm.c -- ALSA SoC PCM
26 #include <sound/soc-dpcm.h>
27 #include <sound/soc-link.h>
64 struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params; in dpcm_show_state()
70 offset += scnprintf(buf + offset, size - offset, in dpcm_show_state()
71 "[%s - %s]\n", fe->dai_link->name, in dpcm_show_state()
74 offset += scnprintf(buf + offset, size - offset, "State: %s\n", in dpcm_show_state()
75 dpcm_state_string(fe->dpcm[stream].state)); in dpcm_show_state()
77 if ((fe->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) && in dpcm_show_state()
78 (fe->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP)) in dpcm_show_state()
79 offset += scnprintf(buf + offset, size - offset, in dpcm_show_state()
87 offset += scnprintf(buf + offset, size - offset, "Backends:\n"); in dpcm_show_state()
89 if (list_empty(&fe->dpcm[stream].be_clients)) { in dpcm_show_state()
90 offset += scnprintf(buf + offset, size - offset, in dpcm_show_state()
95 spin_lock_irqsave(&fe->card->dpcm_lock, flags); in dpcm_show_state()
97 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_show_state()
98 params = &dpcm->hw_params; in dpcm_show_state()
100 offset += scnprintf(buf + offset, size - offset, in dpcm_show_state()
101 "- %s\n", be->dai_link->name); in dpcm_show_state()
103 offset += scnprintf(buf + offset, size - offset, in dpcm_show_state()
105 dpcm_state_string(be->dpcm[stream].state)); in dpcm_show_state()
107 if ((be->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) && in dpcm_show_state()
108 (be->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP)) in dpcm_show_state()
109 offset += scnprintf(buf + offset, size - offset, in dpcm_show_state()
116 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); in dpcm_show_state()
124 struct snd_soc_pcm_runtime *fe = file->private_data; in dpcm_state_read_file()
129 if (fe->num_cpus > 1) { in dpcm_state_read_file()
130 dev_err(fe->dev, in dpcm_state_read_file()
132 return -EINVAL; in dpcm_state_read_file()
137 return -ENOMEM; in dpcm_state_read_file()
143 out_count - offset); in dpcm_state_read_file()
159 if (!rtd->dai_link) in soc_dpcm_debugfs_add()
162 if (!rtd->dai_link->dynamic) in soc_dpcm_debugfs_add()
165 if (!rtd->card->debugfs_card_root) in soc_dpcm_debugfs_add()
168 rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name, in soc_dpcm_debugfs_add()
169 rtd->card->debugfs_card_root); in soc_dpcm_debugfs_add()
171 debugfs_create_file("state", 0444, rtd->debugfs_dpcm_root, in soc_dpcm_debugfs_add()
179 name = kasprintf(GFP_KERNEL, "%s:%s", dpcm->be->dai_link->name, in dpcm_create_debugfs_state()
182 dpcm->debugfs_state = debugfs_create_dir( in dpcm_create_debugfs_state()
183 name, dpcm->fe->debugfs_dpcm_root); in dpcm_create_debugfs_state()
184 debugfs_create_u32("state", 0644, dpcm->debugfs_state, in dpcm_create_debugfs_state()
185 &dpcm->state); in dpcm_create_debugfs_state()
192 debugfs_remove_recursive(dpcm->debugfs_state); in dpcm_remove_debugfs_state()
207 * snd_soc_runtime_action() - Increment/Decrement active count for
211 * @action: Activate stream if 1. Deactivate if -1.
217 * Must be called with the rtd->card->pcm_mutex being held
225 lockdep_assert_held(&rtd->card->pcm_mutex); in snd_soc_runtime_action()
233 * snd_soc_runtime_ignore_pmdown_time() - Check whether to ignore the power down delay
247 if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time) in snd_soc_runtime_ignore_pmdown_time()
251 ignore &= !component->driver->use_pmdown_time; in snd_soc_runtime_ignore_pmdown_time()
257 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
266 struct snd_pcm_runtime *runtime = substream->runtime; in snd_soc_set_runtime_hwparams()
267 runtime->hw.info = hw->info; in snd_soc_set_runtime_hwparams()
268 runtime->hw.formats = hw->formats; in snd_soc_set_runtime_hwparams()
269 runtime->hw.period_bytes_min = hw->period_bytes_min; in snd_soc_set_runtime_hwparams()
270 runtime->hw.period_bytes_max = hw->period_bytes_max; in snd_soc_set_runtime_hwparams()
271 runtime->hw.periods_min = hw->periods_min; in snd_soc_set_runtime_hwparams()
272 runtime->hw.periods_max = hw->periods_max; in snd_soc_set_runtime_hwparams()
273 runtime->hw.buffer_bytes_max = hw->buffer_bytes_max; in snd_soc_set_runtime_hwparams()
274 runtime->hw.fifo_size = hw->fifo_size; in snd_soc_set_runtime_hwparams()
287 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_dapm_stream_event()
289 dev_dbg(be->dev, "ASoC: BE %s event %d dir %d\n", in dpcm_dapm_stream_event()
290 be->dai_link->name, event, dir); in dpcm_dapm_stream_event()
293 (be->dpcm[dir].users >= 1)) in dpcm_dapm_stream_event()
310 if (soc_dai->rate && (soc_dai->driver->symmetric_rates || in soc_pcm_apply_symmetry()
311 rtd->dai_link->symmetric_rates)) { in soc_pcm_apply_symmetry()
312 dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n", in soc_pcm_apply_symmetry()
313 soc_dai->rate); in soc_pcm_apply_symmetry()
315 ret = snd_pcm_hw_constraint_single(substream->runtime, in soc_pcm_apply_symmetry()
317 soc_dai->rate); in soc_pcm_apply_symmetry()
319 dev_err(soc_dai->dev, in soc_pcm_apply_symmetry()
326 if (soc_dai->channels && (soc_dai->driver->symmetric_channels || in soc_pcm_apply_symmetry()
327 rtd->dai_link->symmetric_channels)) { in soc_pcm_apply_symmetry()
328 dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d channel(s)\n", in soc_pcm_apply_symmetry()
329 soc_dai->channels); in soc_pcm_apply_symmetry()
331 ret = snd_pcm_hw_constraint_single(substream->runtime, in soc_pcm_apply_symmetry()
333 soc_dai->channels); in soc_pcm_apply_symmetry()
335 dev_err(soc_dai->dev, in soc_pcm_apply_symmetry()
342 if (soc_dai->sample_bits && (soc_dai->driver->symmetric_samplebits || in soc_pcm_apply_symmetry()
343 rtd->dai_link->symmetric_samplebits)) { in soc_pcm_apply_symmetry()
344 dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d sample bits\n", in soc_pcm_apply_symmetry()
345 soc_dai->sample_bits); in soc_pcm_apply_symmetry()
347 ret = snd_pcm_hw_constraint_single(substream->runtime, in soc_pcm_apply_symmetry()
349 soc_dai->sample_bits); in soc_pcm_apply_symmetry()
351 dev_err(soc_dai->dev, in soc_pcm_apply_symmetry()
374 symmetry = rtd->dai_link->symmetric_rates; in soc_pcm_params_symmetry()
377 symmetry |= dai->driver->symmetric_rates; in soc_pcm_params_symmetry()
381 if (cpu_dai->rate && cpu_dai->rate != rate) { in soc_pcm_params_symmetry()
382 dev_err(rtd->dev, "ASoC: unmatched rate symmetry: %d - %d\n", in soc_pcm_params_symmetry()
383 cpu_dai->rate, rate); in soc_pcm_params_symmetry()
384 return -EINVAL; in soc_pcm_params_symmetry()
389 symmetry = rtd->dai_link->symmetric_channels; in soc_pcm_params_symmetry()
392 symmetry |= dai->driver->symmetric_channels; in soc_pcm_params_symmetry()
396 if (cpu_dai->channels && in soc_pcm_params_symmetry()
397 cpu_dai->channels != channels) { in soc_pcm_params_symmetry()
398 dev_err(rtd->dev, "ASoC: unmatched channel symmetry: %d - %d\n", in soc_pcm_params_symmetry()
399 cpu_dai->channels, channels); in soc_pcm_params_symmetry()
400 return -EINVAL; in soc_pcm_params_symmetry()
405 symmetry = rtd->dai_link->symmetric_samplebits; in soc_pcm_params_symmetry()
408 symmetry |= dai->driver->symmetric_samplebits; in soc_pcm_params_symmetry()
412 if (cpu_dai->sample_bits && in soc_pcm_params_symmetry()
413 cpu_dai->sample_bits != sample_bits) { in soc_pcm_params_symmetry()
414 dev_err(rtd->dev, "ASoC: unmatched sample bits symmetry: %d - %d\n", in soc_pcm_params_symmetry()
415 cpu_dai->sample_bits, sample_bits); in soc_pcm_params_symmetry()
416 return -EINVAL; in soc_pcm_params_symmetry()
427 struct snd_soc_dai_link *link = rtd->dai_link; in soc_pcm_has_symmetry()
431 symmetry = link->symmetric_rates || in soc_pcm_has_symmetry()
432 link->symmetric_channels || in soc_pcm_has_symmetry()
433 link->symmetric_samplebits; in soc_pcm_has_symmetry()
437 dai->driver->symmetric_rates || in soc_pcm_has_symmetry()
438 dai->driver->symmetric_channels || in soc_pcm_has_symmetry()
439 dai->driver->symmetric_samplebits; in soc_pcm_has_symmetry()
452 ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 0, bits); in soc_pcm_set_msb()
454 dev_warn(rtd->dev, "ASoC: Failed to set MSB %d: %d\n", in soc_pcm_set_msb()
464 int stream = substream->stream; in soc_pcm_apply_msb()
471 if (pcm_codec->sig_bits == 0) { in soc_pcm_apply_msb()
475 bits = max(pcm_codec->sig_bits, bits); in soc_pcm_apply_msb()
481 if (pcm_cpu->sig_bits == 0) { in soc_pcm_apply_msb()
485 cpu_bits = max(pcm_cpu->sig_bits, cpu_bits); in soc_pcm_apply_msb()
493 * snd_soc_runtime_calc_hw() - Calculate hw limits for a PCM stream
520 * Skip CPUs which don't support the current stream type. in snd_soc_runtime_calc_hw()
530 cpu_chan_min = max(cpu_chan_min, cpu_stream->channels_min); in snd_soc_runtime_calc_hw()
531 cpu_chan_max = min(cpu_chan_max, cpu_stream->channels_max); in snd_soc_runtime_calc_hw()
532 cpu_rate_min = max(cpu_rate_min, cpu_stream->rate_min); in snd_soc_runtime_calc_hw()
533 cpu_rate_max = min_not_zero(cpu_rate_max, cpu_stream->rate_max); in snd_soc_runtime_calc_hw()
534 formats &= cpu_stream->formats; in snd_soc_runtime_calc_hw()
535 cpu_rates = snd_pcm_rate_mask_intersect(cpu_stream->rates, in snd_soc_runtime_calc_hw()
543 * Skip CODECs which don't support the current stream type. in snd_soc_runtime_calc_hw()
553 chan_min = max(chan_min, codec_stream->channels_min); in snd_soc_runtime_calc_hw()
554 chan_max = min(chan_max, codec_stream->channels_max); in snd_soc_runtime_calc_hw()
555 rate_min = max(rate_min, codec_stream->rate_min); in snd_soc_runtime_calc_hw()
556 rate_max = min_not_zero(rate_max, codec_stream->rate_max); in snd_soc_runtime_calc_hw()
557 formats &= codec_stream->formats; in snd_soc_runtime_calc_hw()
558 rates = snd_pcm_rate_mask_intersect(codec_stream->rates, rates); in snd_soc_runtime_calc_hw()
563 return -EINVAL; in snd_soc_runtime_calc_hw()
570 if (rtd->num_codecs > 1) { in snd_soc_runtime_calc_hw()
576 hw->channels_min = max(chan_min, cpu_chan_min); in snd_soc_runtime_calc_hw()
577 hw->channels_max = min(chan_max, cpu_chan_max); in snd_soc_runtime_calc_hw()
578 hw->formats = formats; in snd_soc_runtime_calc_hw()
579 hw->rates = snd_pcm_rate_mask_intersect(rates, cpu_rates); in snd_soc_runtime_calc_hw()
583 hw->rate_min = max(hw->rate_min, cpu_rate_min); in snd_soc_runtime_calc_hw()
584 hw->rate_min = max(hw->rate_min, rate_min); in snd_soc_runtime_calc_hw()
585 hw->rate_max = min_not_zero(hw->rate_max, cpu_rate_max); in snd_soc_runtime_calc_hw()
586 hw->rate_max = min_not_zero(hw->rate_max, rate_max); in snd_soc_runtime_calc_hw()
594 struct snd_pcm_hardware *hw = &substream->runtime->hw; in soc_pcm_init_runtime_hw()
596 u64 formats = hw->formats; in soc_pcm_init_runtime_hw()
603 snd_soc_runtime_calc_hw(rtd, hw, substream->stream); in soc_pcm_init_runtime_hw()
606 hw->formats &= formats; in soc_pcm_init_runtime_hw()
653 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); in soc_pcm_clean()
656 snd_soc_runtime_deactivate(rtd, substream->stream); in soc_pcm_clean()
666 snd_soc_dapm_stream_stop(rtd, substream->stream); in soc_pcm_clean()
668 mutex_unlock(&rtd->card->pcm_mutex); in soc_pcm_clean()
674 pinctrl_pm_select_sleep_state(component->dev); in soc_pcm_clean()
690 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
697 struct snd_pcm_runtime *runtime = substream->runtime; in soc_pcm_open()
705 pinctrl_pm_select_default_state(component->dev); in soc_pcm_open()
711 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); in soc_pcm_open()
729 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) in soc_pcm_open()
735 if (rtd->num_codecs == 1) in soc_pcm_open()
736 codec_dai_name = asoc_rtd_to_codec(rtd, 0)->name; in soc_pcm_open()
738 if (rtd->num_cpus == 1) in soc_pcm_open()
739 cpu_dai_name = asoc_rtd_to_cpu(rtd, 0)->name; in soc_pcm_open()
742 runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; in soc_pcm_open()
744 ret = -EINVAL; in soc_pcm_open()
745 if (!runtime->hw.rates) { in soc_pcm_open()
746 printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n", in soc_pcm_open()
750 if (!runtime->hw.formats) { in soc_pcm_open()
751 printk(KERN_ERR "ASoC: %s <-> %s No matching formats\n", in soc_pcm_open()
755 if (!runtime->hw.channels_min || !runtime->hw.channels_max || in soc_pcm_open()
756 runtime->hw.channels_min > runtime->hw.channels_max) { in soc_pcm_open()
757 printk(KERN_ERR "ASoC: %s <-> %s No matching channels\n", in soc_pcm_open()
773 pr_debug("ASoC: %s <-> %s info:\n", in soc_pcm_open()
775 pr_debug("ASoC: rate mask 0x%x\n", runtime->hw.rates); in soc_pcm_open()
776 pr_debug("ASoC: min ch %d max ch %d\n", runtime->hw.channels_min, in soc_pcm_open()
777 runtime->hw.channels_max); in soc_pcm_open()
778 pr_debug("ASoC: min rate %d max rate %d\n", runtime->hw.rate_min, in soc_pcm_open()
779 runtime->hw.rate_max); in soc_pcm_open()
781 snd_soc_runtime_activate(rtd, substream->stream); in soc_pcm_open()
784 mutex_unlock(&rtd->card->pcm_mutex); in soc_pcm_open()
813 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); in soc_pcm_prepare()
825 dev_err(rtd->dev, "ASoC: DAI prepare error: %d\n", ret); in soc_pcm_prepare()
830 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && in soc_pcm_prepare()
831 rtd->pop_wait) { in soc_pcm_prepare()
832 rtd->pop_wait = 0; in soc_pcm_prepare()
833 cancel_delayed_work(&rtd->delayed_work); in soc_pcm_prepare()
836 snd_soc_dapm_stream_event(rtd, substream->stream, in soc_pcm_prepare()
840 snd_soc_dai_digital_mute(dai, 0, substream->stream); in soc_pcm_prepare()
843 mutex_unlock(&rtd->card->pcm_mutex); in soc_pcm_prepare()
854 interval->min = channels; in soc_pcm_codec_params_fixup()
855 interval->max = channels; in soc_pcm_codec_params_fixup()
861 * (using snd_pcm_lib_* ). It's non-atomic.
872 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); in soc_pcm_hw_params()
886 * Skip CODECs which don't support the current stream type, in soc_pcm_hw_params()
893 * capture-only CODEC is acting as an LRCLK and/or BCLK master in soc_pcm_hw_params()
894 * for the DAI link including a playback-only CODEC. in soc_pcm_hw_params()
899 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream)) in soc_pcm_hw_params()
906 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && in soc_pcm_hw_params()
907 codec_dai->tx_mask) in soc_pcm_hw_params()
909 codec_dai->tx_mask); in soc_pcm_hw_params()
911 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && in soc_pcm_hw_params()
912 codec_dai->rx_mask) in soc_pcm_hw_params()
914 codec_dai->rx_mask); in soc_pcm_hw_params()
921 codec_dai->rate = params_rate(&codec_params); in soc_pcm_hw_params()
922 codec_dai->channels = params_channels(&codec_params); in soc_pcm_hw_params()
923 codec_dai->sample_bits = snd_pcm_format_physical_width( in soc_pcm_hw_params()
931 * Skip CPUs which don't support the current stream in soc_pcm_hw_params()
934 if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) in soc_pcm_hw_params()
942 cpu_dai->rate = params_rate(params); in soc_pcm_hw_params()
943 cpu_dai->channels = params_channels(params); in soc_pcm_hw_params()
944 cpu_dai->sample_bits = in soc_pcm_hw_params()
955 mutex_unlock(&rtd->card->pcm_mutex); in soc_pcm_hw_params()
961 i = rtd->num_cpus; in soc_pcm_hw_params()
965 if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) in soc_pcm_hw_params()
969 cpu_dai->rate = 0; in soc_pcm_hw_params()
972 i = rtd->num_codecs; in soc_pcm_hw_params()
976 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream)) in soc_pcm_hw_params()
980 codec_dai->rate = 0; in soc_pcm_hw_params()
985 mutex_unlock(&rtd->card->pcm_mutex); in soc_pcm_hw_params()
998 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass); in soc_pcm_hw_free()
1002 int active = snd_soc_dai_stream_active(dai, substream->stream); in soc_pcm_hw_free()
1005 dai->rate = 0; in soc_pcm_hw_free()
1006 dai->channels = 0; in soc_pcm_hw_free()
1007 dai->sample_bits = 0; in soc_pcm_hw_free()
1011 snd_soc_dai_digital_mute(dai, 1, substream->stream); in soc_pcm_hw_free()
1022 if (!snd_soc_dai_stream_valid(dai, substream->stream)) in soc_pcm_hw_free()
1028 mutex_unlock(&rtd->card->pcm_mutex); in soc_pcm_hw_free()
1034 int ret = -EINVAL; in soc_pcm_trigger()
1071 * the runtime->delay will be updated accordingly.
1078 struct snd_pcm_runtime *runtime = substream->runtime; in soc_pcm_pointer()
1086 runtime->delay = 0; in soc_pcm_pointer()
1091 delay = runtime->delay; in soc_pcm_pointer()
1105 runtime->delay = delay; in soc_pcm_pointer()
1119 if (dpcm->be == be && dpcm->fe == fe) in dpcm_be_connect()
1125 return -ENOMEM; in dpcm_be_connect()
1127 dpcm->be = be; in dpcm_be_connect()
1128 dpcm->fe = fe; in dpcm_be_connect()
1129 be->dpcm[stream].runtime = fe->dpcm[stream].runtime; in dpcm_be_connect()
1130 dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW; in dpcm_be_connect()
1131 spin_lock_irqsave(&fe->card->dpcm_lock, flags); in dpcm_be_connect()
1132 list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients); in dpcm_be_connect()
1133 list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients); in dpcm_be_connect()
1134 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); in dpcm_be_connect()
1136 dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n", in dpcm_be_connect()
1137 stream ? "capture" : "playback", fe->dai_link->name, in dpcm_be_connect()
1138 stream ? "<-" : "->", be->dai_link->name); in dpcm_be_connect()
1153 if (!be->dpcm[stream].users) in dpcm_be_reparent()
1161 if (dpcm->fe == fe) in dpcm_be_reparent()
1164 dev_dbg(fe->dev, "reparent %s path %s %s %s\n", in dpcm_be_reparent()
1166 dpcm->fe->dai_link->name, in dpcm_be_reparent()
1167 stream ? "<-" : "->", dpcm->be->dai_link->name); in dpcm_be_reparent()
1169 fe_substream = snd_soc_dpcm_get_substream(dpcm->fe, stream); in dpcm_be_reparent()
1170 be_substream->runtime = fe_substream->runtime; in dpcm_be_reparent()
1182 dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n", in dpcm_be_disconnect()
1184 dpcm->be->dai_link->name); in dpcm_be_disconnect()
1186 if (dpcm->state != SND_SOC_DPCM_LINK_STATE_FREE) in dpcm_be_disconnect()
1189 dev_dbg(fe->dev, "freed DSP %s path %s %s %s\n", in dpcm_be_disconnect()
1190 stream ? "capture" : "playback", fe->dai_link->name, in dpcm_be_disconnect()
1191 stream ? "<-" : "->", dpcm->be->dai_link->name); in dpcm_be_disconnect()
1194 dpcm_be_reparent(fe, dpcm->be, stream); in dpcm_be_disconnect()
1198 spin_lock_irqsave(&fe->card->dpcm_lock, flags); in dpcm_be_disconnect()
1199 list_del(&dpcm->list_be); in dpcm_be_disconnect()
1200 list_del(&dpcm->list_fe); in dpcm_be_disconnect()
1201 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); in dpcm_be_disconnect()
1215 dev_dbg(card->dev, "ASoC: find BE for widget %s\n", widget->name); in dpcm_get_be()
1219 if (!be->dai_link->no_pcm) in dpcm_get_be()
1225 dev_dbg(card->dev, "ASoC: try BE : %s\n", in dpcm_get_be()
1226 w ? w->name : "(not set)"); in dpcm_get_be()
1253 struct snd_soc_card *card = widget->dapm->card; in dpcm_end_walk_at_be()
1276 if (fe->num_cpus > 1) { in dpcm_path_get()
1277 dev_err(fe->dev, in dpcm_path_get()
1279 return -EINVAL; in dpcm_path_get()
1286 dev_dbg(fe->dev, "ASoC: found %d audio %s paths\n", paths, in dpcm_path_get()
1305 for_each_rtd_dais(dpcm->be, i, dai) { in dpcm_be_is_active()
1325 /* Destroy any old FE <--> BE connections */ in dpcm_prune_paths()
1330 dev_dbg(fe->dev, "ASoC: pruning %s BE %s for %s\n", in dpcm_prune_paths()
1332 dpcm->be->dai_link->name, fe->dai_link->name); in dpcm_prune_paths()
1333 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; in dpcm_prune_paths()
1334 dpcm->be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; in dpcm_prune_paths()
1338 dev_dbg(fe->dev, "ASoC: found %d old BE paths for pruning\n", prune); in dpcm_prune_paths()
1345 struct snd_soc_card *card = fe->card; in dpcm_add_paths()
1351 /* Create any new FE <--> BE connections */ in dpcm_add_paths()
1354 switch (widget->id) { in dpcm_add_paths()
1370 dev_err(fe->dev, "ASoC: no BE found for %s\n", in dpcm_add_paths()
1371 widget->name); in dpcm_add_paths()
1376 if (!fe->dpcm[stream].runtime && !fe->fe_compr) in dpcm_add_paths()
1382 dev_err(fe->dev, "ASoC: can't connect %s\n", in dpcm_add_paths()
1383 widget->name); in dpcm_add_paths()
1389 be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE; in dpcm_add_paths()
1393 dev_dbg(fe->dev, "ASoC: found %d new BE paths\n", new); in dpcm_add_paths()
1415 spin_lock_irqsave(&fe->card->dpcm_lock, flags); in dpcm_clear_pending_state()
1417 dpcm->be->dpcm[stream].runtime_update = in dpcm_clear_pending_state()
1419 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); in dpcm_clear_pending_state()
1430 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_be_dai_startup_unwind()
1434 if (be->dpcm[stream].users == 0) in dpcm_be_dai_startup_unwind()
1435 dev_err(be->dev, "ASoC: no users %s at close - state %d\n", in dpcm_be_dai_startup_unwind()
1437 be->dpcm[stream].state); in dpcm_be_dai_startup_unwind()
1439 if (--be->dpcm[stream].users != 0) in dpcm_be_dai_startup_unwind()
1442 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) in dpcm_be_dai_startup_unwind()
1446 be_substream->runtime = NULL; in dpcm_be_dai_startup_unwind()
1447 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; in dpcm_be_dai_startup_unwind()
1456 /* only startup BE DAIs that are either sinks or sources to this FE DAI */ in dpcm_be_dai_startup()
1459 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_be_dai_startup()
1464 dev_err(be->dev, "ASoC: no backend %s stream\n", in dpcm_be_dai_startup()
1474 if (be->dpcm[stream].users == DPCM_MAX_BE_USERS) in dpcm_be_dai_startup()
1475 dev_err(be->dev, "ASoC: too many users %s at open %d\n", in dpcm_be_dai_startup()
1477 be->dpcm[stream].state); in dpcm_be_dai_startup()
1479 if (be->dpcm[stream].users++ != 0) in dpcm_be_dai_startup()
1482 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_NEW) && in dpcm_be_dai_startup()
1483 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE)) in dpcm_be_dai_startup()
1486 dev_dbg(be->dev, "ASoC: open %s BE %s\n", in dpcm_be_dai_startup()
1487 stream ? "capture" : "playback", be->dai_link->name); in dpcm_be_dai_startup()
1489 be_substream->runtime = be->dpcm[stream].runtime; in dpcm_be_dai_startup()
1492 dev_err(be->dev, "ASoC: BE open failed %d\n", err); in dpcm_be_dai_startup()
1493 be->dpcm[stream].users--; in dpcm_be_dai_startup()
1494 if (be->dpcm[stream].users < 0) in dpcm_be_dai_startup()
1495 dev_err(be->dev, "ASoC: no users %s at unwind %d\n", in dpcm_be_dai_startup()
1497 be->dpcm[stream].state); in dpcm_be_dai_startup()
1499 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; in dpcm_be_dai_startup()
1503 be->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; in dpcm_be_dai_startup()
1512 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_be_dai_startup()
1519 if (be->dpcm[stream].users == 0) in dpcm_be_dai_startup()
1520 dev_err(be->dev, "ASoC: no users %s at close %d\n", in dpcm_be_dai_startup()
1522 be->dpcm[stream].state); in dpcm_be_dai_startup()
1524 if (--be->dpcm[stream].users != 0) in dpcm_be_dai_startup()
1527 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) in dpcm_be_dai_startup()
1531 be_substream->runtime = NULL; in dpcm_be_dai_startup()
1532 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; in dpcm_be_dai_startup()
1541 runtime->hw.rate_min = stream->rate_min; in dpcm_init_runtime_hw()
1542 runtime->hw.rate_max = min_not_zero(stream->rate_max, UINT_MAX); in dpcm_init_runtime_hw()
1543 runtime->hw.channels_min = stream->channels_min; in dpcm_init_runtime_hw()
1544 runtime->hw.channels_max = stream->channels_max; in dpcm_init_runtime_hw()
1545 if (runtime->hw.formats) in dpcm_init_runtime_hw()
1546 runtime->hw.formats &= stream->formats; in dpcm_init_runtime_hw()
1548 runtime->hw.formats = stream->formats; in dpcm_init_runtime_hw()
1549 runtime->hw.rates = stream->rates; in dpcm_init_runtime_hw()
1558 int stream = substream->stream; in dpcm_runtime_merge_format()
1560 if (!fe->dai_link->dpcm_merged_format) in dpcm_runtime_merge_format()
1569 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_runtime_merge_format()
1575 * Skip CODECs which don't support the current stream in dpcm_runtime_merge_format()
1583 *formats &= codec_stream->formats; in dpcm_runtime_merge_format()
1594 int stream = substream->stream; in dpcm_runtime_merge_chan()
1596 if (!fe->dai_link->dpcm_merged_chan) in dpcm_runtime_merge_chan()
1605 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_runtime_merge_chan()
1613 * Skip CPUs which don't support the current stream in dpcm_runtime_merge_chan()
1622 cpu_stream->channels_min); in dpcm_runtime_merge_chan()
1624 cpu_stream->channels_max); in dpcm_runtime_merge_chan()
1631 if (be->num_codecs == 1) { in dpcm_runtime_merge_chan()
1635 codec_stream->channels_min); in dpcm_runtime_merge_chan()
1637 codec_stream->channels_max); in dpcm_runtime_merge_chan()
1649 int stream = substream->stream; in dpcm_runtime_merge_rate()
1651 if (!fe->dai_link->dpcm_merged_rate) in dpcm_runtime_merge_rate()
1660 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_runtime_merge_rate()
1667 * Skip DAIs which don't support the current stream in dpcm_runtime_merge_rate()
1675 *rate_min = max(*rate_min, pcm->rate_min); in dpcm_runtime_merge_rate()
1676 *rate_max = min_not_zero(*rate_max, pcm->rate_max); in dpcm_runtime_merge_rate()
1677 *rates = snd_pcm_rate_mask_intersect(*rates, pcm->rates); in dpcm_runtime_merge_rate()
1684 struct snd_pcm_runtime *runtime = substream->runtime; in dpcm_set_fe_runtime()
1691 * Skip CPUs which don't support the current stream in dpcm_set_fe_runtime()
1694 if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream)) in dpcm_set_fe_runtime()
1699 substream->stream)); in dpcm_set_fe_runtime()
1702 dpcm_runtime_merge_format(substream, &runtime->hw.formats); in dpcm_set_fe_runtime()
1703 dpcm_runtime_merge_chan(substream, &runtime->hw.channels_min, in dpcm_set_fe_runtime()
1704 &runtime->hw.channels_max); in dpcm_set_fe_runtime()
1705 dpcm_runtime_merge_rate(substream, &runtime->hw.rates, in dpcm_set_fe_runtime()
1706 &runtime->hw.rate_min, &runtime->hw.rate_max); in dpcm_set_fe_runtime()
1723 if (state == SND_SOC_DPCM_UPDATE_NO && fe->dpcm[stream].trigger_pending) { in dpcm_set_fe_update_state()
1725 fe->dpcm[stream].trigger_pending - 1); in dpcm_set_fe_update_state()
1726 fe->dpcm[stream].trigger_pending = 0; in dpcm_set_fe_update_state()
1728 fe->dpcm[stream].runtime_update = state; in dpcm_set_fe_update_state()
1743 fe_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; in dpcm_apply_symmetry()
1756 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_apply_symmetry()
1768 if (rtd->dai_link->be_hw_params_fixup) in dpcm_apply_symmetry()
1772 be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; in dpcm_apply_symmetry()
1790 struct snd_pcm_runtime *runtime = fe_substream->runtime; in dpcm_fe_dai_startup()
1791 int stream = fe_substream->stream, ret = 0; in dpcm_fe_dai_startup()
1797 dev_err(fe->dev,"ASoC: failed to start some BEs %d\n", ret); in dpcm_fe_dai_startup()
1801 dev_dbg(fe->dev, "ASoC: open FE %s\n", fe->dai_link->name); in dpcm_fe_dai_startup()
1806 dev_err(fe->dev,"ASoC: failed to start FE %d\n", ret); in dpcm_fe_dai_startup()
1810 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN; in dpcm_fe_dai_startup()
1817 dev_err(fe->dev, "ASoC: failed to apply dpcm symmetry %d\n", in dpcm_fe_dai_startup()
1832 /* only shutdown BEs that are either sinks or sources to this FE DAI */ in dpcm_be_dai_shutdown()
1835 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_be_dai_shutdown()
1843 if (be->dpcm[stream].users == 0) in dpcm_be_dai_shutdown()
1844 dev_err(be->dev, "ASoC: no users %s at close - state %d\n", in dpcm_be_dai_shutdown()
1846 be->dpcm[stream].state); in dpcm_be_dai_shutdown()
1848 if (--be->dpcm[stream].users != 0) in dpcm_be_dai_shutdown()
1851 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && in dpcm_be_dai_shutdown()
1852 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)) { in dpcm_be_dai_shutdown()
1854 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE; in dpcm_be_dai_shutdown()
1857 dev_dbg(be->dev, "ASoC: close BE %s\n", in dpcm_be_dai_shutdown()
1858 be->dai_link->name); in dpcm_be_dai_shutdown()
1861 be_substream->runtime = NULL; in dpcm_be_dai_shutdown()
1863 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; in dpcm_be_dai_shutdown()
1871 int stream = substream->stream; in dpcm_fe_dai_shutdown()
1878 dev_dbg(fe->dev, "ASoC: close FE %s\n", fe->dai_link->name); in dpcm_fe_dai_shutdown()
1886 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE; in dpcm_fe_dai_shutdown()
1895 /* only hw_params backends that are either sinks or sources in dpcm_be_dai_hw_free()
1899 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_be_dai_hw_free()
1907 /* only free hw when no longer used - check all FEs */ in dpcm_be_dai_hw_free()
1912 if (be->dpcm[stream].users > 1) in dpcm_be_dai_hw_free()
1915 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && in dpcm_be_dai_hw_free()
1916 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && in dpcm_be_dai_hw_free()
1917 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && in dpcm_be_dai_hw_free()
1918 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) && in dpcm_be_dai_hw_free()
1919 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && in dpcm_be_dai_hw_free()
1920 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND)) in dpcm_be_dai_hw_free()
1923 dev_dbg(be->dev, "ASoC: hw_free BE %s\n", in dpcm_be_dai_hw_free()
1924 be->dai_link->name); in dpcm_be_dai_hw_free()
1928 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE; in dpcm_be_dai_hw_free()
1937 int err, stream = substream->stream; in dpcm_fe_dai_hw_free()
1939 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); in dpcm_fe_dai_hw_free()
1942 dev_dbg(fe->dev, "ASoC: hw_free FE %s\n", fe->dai_link->name); in dpcm_fe_dai_hw_free()
1947 dev_err(fe->dev,"ASoC: hw_free FE %s failed\n", in dpcm_fe_dai_hw_free()
1948 fe->dai_link->name); in dpcm_fe_dai_hw_free()
1950 /* only hw_params backends that are either sinks or sources in dpcm_fe_dai_hw_free()
1954 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE; in dpcm_fe_dai_hw_free()
1957 mutex_unlock(&fe->card->mutex); in dpcm_fe_dai_hw_free()
1968 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_be_dai_hw_params()
1977 memcpy(&dpcm->hw_params, &fe->dpcm[stream].hw_params, in dpcm_be_dai_hw_params()
1981 ret = snd_soc_link_be_hw_params_fixup(be, &dpcm->hw_params); in dpcm_be_dai_hw_params()
1985 /* copy the fixed-up hw params for BE dai */ in dpcm_be_dai_hw_params()
1986 memcpy(&be->dpcm[stream].hw_params, &dpcm->hw_params, in dpcm_be_dai_hw_params()
1993 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) && in dpcm_be_dai_hw_params()
1994 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && in dpcm_be_dai_hw_params()
1995 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE)) in dpcm_be_dai_hw_params()
1998 dev_dbg(be->dev, "ASoC: hw_params BE %s\n", in dpcm_be_dai_hw_params()
1999 be->dai_link->name); in dpcm_be_dai_hw_params()
2001 ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); in dpcm_be_dai_hw_params()
2003 dev_err(dpcm->be->dev, in dpcm_be_dai_hw_params()
2008 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS; in dpcm_be_dai_hw_params()
2015 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_be_dai_hw_params()
2026 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) && in dpcm_be_dai_hw_params()
2027 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && in dpcm_be_dai_hw_params()
2028 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) && in dpcm_be_dai_hw_params()
2029 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)) in dpcm_be_dai_hw_params()
2042 int ret, stream = substream->stream; in dpcm_fe_dai_hw_params()
2044 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); in dpcm_fe_dai_hw_params()
2047 memcpy(&fe->dpcm[stream].hw_params, params, in dpcm_fe_dai_hw_params()
2051 dev_err(fe->dev,"ASoC: hw_params BE failed %d\n", ret); in dpcm_fe_dai_hw_params()
2055 dev_dbg(fe->dev, "ASoC: hw_params FE %s rate %d chan %x fmt %d\n", in dpcm_fe_dai_hw_params()
2056 fe->dai_link->name, params_rate(params), in dpcm_fe_dai_hw_params()
2062 dev_err(fe->dev,"ASoC: hw_params FE failed %d\n", ret); in dpcm_fe_dai_hw_params()
2065 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS; in dpcm_fe_dai_hw_params()
2069 mutex_unlock(&fe->card->mutex); in dpcm_fe_dai_hw_params()
2078 dev_dbg(dpcm->be->dev, "ASoC: trigger BE %s cmd %d\n", in dpcm_do_trigger()
2079 dpcm->be->dai_link->name, cmd); in dpcm_do_trigger()
2083 dev_err(dpcm->be->dev,"ASoC: trigger BE failed %d\n", ret); in dpcm_do_trigger()
2096 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_be_dai_trigger()
2106 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) && in dpcm_be_dai_trigger()
2107 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && in dpcm_be_dai_trigger()
2108 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) in dpcm_be_dai_trigger()
2115 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; in dpcm_be_dai_trigger()
2118 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND)) in dpcm_be_dai_trigger()
2125 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; in dpcm_be_dai_trigger()
2128 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) in dpcm_be_dai_trigger()
2135 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START; in dpcm_be_dai_trigger()
2138 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) && in dpcm_be_dai_trigger()
2139 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) in dpcm_be_dai_trigger()
2149 be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; in dpcm_be_dai_trigger()
2152 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) in dpcm_be_dai_trigger()
2162 be->dpcm[stream].state = SND_SOC_DPCM_STATE_SUSPEND; in dpcm_be_dai_trigger()
2165 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START) in dpcm_be_dai_trigger()
2175 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED; in dpcm_be_dai_trigger()
2192 dev_dbg(fe->dev, "ASoC: pre trigger FE %s cmd %d\n", in dpcm_dai_trigger_fe_be()
2193 fe->dai_link->name, cmd); in dpcm_dai_trigger_fe_be()
2199 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); in dpcm_dai_trigger_fe_be()
2204 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd); in dpcm_dai_trigger_fe_be()
2208 dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n", in dpcm_dai_trigger_fe_be()
2209 fe->dai_link->name, cmd); in dpcm_dai_trigger_fe_be()
2219 int stream = substream->stream; in dpcm_fe_dai_do_trigger()
2221 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; in dpcm_fe_dai_do_trigger()
2223 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE; in dpcm_fe_dai_do_trigger()
2240 ret = -EINVAL; in dpcm_fe_dai_do_trigger()
2258 ret = -EINVAL; in dpcm_fe_dai_do_trigger()
2263 /* bespoke trigger() - handles both FE and BEs */ in dpcm_fe_dai_do_trigger()
2265 dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd %d\n", in dpcm_fe_dai_do_trigger()
2266 fe->dai_link->name, cmd); in dpcm_fe_dai_do_trigger()
2271 dev_err(fe->dev, "ASoC: invalid trigger cmd %d for %s\n", cmd, in dpcm_fe_dai_do_trigger()
2272 fe->dai_link->name); in dpcm_fe_dai_do_trigger()
2273 ret = -EINVAL; in dpcm_fe_dai_do_trigger()
2278 dev_err(fe->dev, "ASoC: trigger FE cmd: %d failed: %d\n", in dpcm_fe_dai_do_trigger()
2287 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START; in dpcm_fe_dai_do_trigger()
2291 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP; in dpcm_fe_dai_do_trigger()
2294 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED; in dpcm_fe_dai_do_trigger()
2299 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO; in dpcm_fe_dai_do_trigger()
2306 int stream = substream->stream; in dpcm_fe_dai_trigger()
2311 if (fe->dpcm[stream].runtime_update != SND_SOC_DPCM_UPDATE_NO) { in dpcm_fe_dai_trigger()
2312 fe->dpcm[stream].trigger_pending = cmd + 1; in dpcm_fe_dai_trigger()
2327 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_be_dai_prepare()
2338 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) && in dpcm_be_dai_prepare()
2339 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) && in dpcm_be_dai_prepare()
2340 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND) && in dpcm_be_dai_prepare()
2341 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED)) in dpcm_be_dai_prepare()
2344 dev_dbg(be->dev, "ASoC: prepare BE %s\n", in dpcm_be_dai_prepare()
2345 be->dai_link->name); in dpcm_be_dai_prepare()
2349 dev_err(be->dev, "ASoC: backend prepare failed %d\n", in dpcm_be_dai_prepare()
2354 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE; in dpcm_be_dai_prepare()
2362 int stream = substream->stream, ret = 0; in dpcm_fe_dai_prepare()
2364 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); in dpcm_fe_dai_prepare()
2366 dev_dbg(fe->dev, "ASoC: prepare FE %s\n", fe->dai_link->name); in dpcm_fe_dai_prepare()
2371 if (list_empty(&fe->dpcm[stream].be_clients)) { in dpcm_fe_dai_prepare()
2372 dev_err(fe->dev, "ASoC: no backend DAIs enabled for %s\n", in dpcm_fe_dai_prepare()
2373 fe->dai_link->name); in dpcm_fe_dai_prepare()
2374 ret = -EINVAL; in dpcm_fe_dai_prepare()
2385 dev_err(fe->dev,"ASoC: prepare FE %s failed\n", in dpcm_fe_dai_prepare()
2386 fe->dai_link->name); in dpcm_fe_dai_prepare()
2392 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE; in dpcm_fe_dai_prepare()
2396 mutex_unlock(&fe->card->mutex); in dpcm_fe_dai_prepare()
2405 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; in dpcm_run_update_shutdown()
2408 dev_dbg(fe->dev, "ASoC: runtime %s close on FE %s\n", in dpcm_run_update_shutdown()
2409 stream ? "capture" : "playback", fe->dai_link->name); in dpcm_run_update_shutdown()
2412 /* call bespoke trigger - FE takes care of all BE triggers */ in dpcm_run_update_shutdown()
2413 dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd stop\n", in dpcm_run_update_shutdown()
2414 fe->dai_link->name); in dpcm_run_update_shutdown()
2418 dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err); in dpcm_run_update_shutdown()
2420 dev_dbg(fe->dev, "ASoC: trigger FE %s cmd stop\n", in dpcm_run_update_shutdown()
2421 fe->dai_link->name); in dpcm_run_update_shutdown()
2425 dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err); in dpcm_run_update_shutdown()
2430 dev_err(fe->dev,"ASoC: hw_free FE failed %d\n", err); in dpcm_run_update_shutdown()
2434 dev_err(fe->dev,"ASoC: shutdown FE failed %d\n", err); in dpcm_run_update_shutdown()
2447 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream]; in dpcm_run_update_startup()
2451 dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n", in dpcm_run_update_startup()
2452 stream ? "capture" : "playback", fe->dai_link->name); in dpcm_run_update_startup()
2455 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_HW_FREE || in dpcm_run_update_startup()
2456 fe->dpcm[stream].state == SND_SOC_DPCM_STATE_CLOSE) in dpcm_run_update_startup()
2457 return -EINVAL; in dpcm_run_update_startup()
2465 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_OPEN) in dpcm_run_update_startup()
2473 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_HW_PARAMS) in dpcm_run_update_startup()
2485 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_PREPARE || in dpcm_run_update_startup()
2486 fe->dpcm[stream].state == SND_SOC_DPCM_STATE_STOP) in dpcm_run_update_startup()
2490 /* call trigger on the frontend - FE takes care of all BE triggers */ in dpcm_run_update_startup()
2491 dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd start\n", in dpcm_run_update_startup()
2492 fe->dai_link->name); in dpcm_run_update_startup()
2496 dev_err(fe->dev,"ASoC: bespoke trigger FE failed %d\n", ret); in dpcm_run_update_startup()
2500 dev_dbg(fe->dev, "ASoC: trigger FE %s cmd start\n", in dpcm_run_update_startup()
2501 fe->dai_link->name); in dpcm_run_update_startup()
2506 dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret); in dpcm_run_update_startup()
2519 spin_lock_irqsave(&fe->card->dpcm_lock, flags); in dpcm_run_update_startup()
2521 struct snd_soc_pcm_runtime *be = dpcm->be; in dpcm_run_update_startup()
2522 if (be->dpcm[stream].state == SND_SOC_DPCM_STATE_CLOSE) in dpcm_run_update_startup()
2523 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; in dpcm_run_update_startup()
2525 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); in dpcm_run_update_startup()
2537 if (!fe->dai_link->dynamic) in soc_dpcm_fe_runtime_update()
2540 if (fe->num_cpus > 1) { in soc_dpcm_fe_runtime_update()
2541 dev_err(fe->dev, in soc_dpcm_fe_runtime_update()
2543 return -EINVAL; in soc_dpcm_fe_runtime_update()
2551 dev_dbg(fe->dev, "ASoC: DPCM %s runtime update for FE %s\n", in soc_dpcm_fe_runtime_update()
2552 new ? "new" : "old", fe->dai_link->name); in soc_dpcm_fe_runtime_update()
2568 dev_warn(fe->dev, "ASoC: %s no valid %s path\n", in soc_dpcm_fe_runtime_update()
2569 fe->dai_link->name, in soc_dpcm_fe_runtime_update()
2584 dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n"); in soc_dpcm_fe_runtime_update()
2605 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME); in snd_soc_dpcm_runtime_update()
2621 mutex_unlock(&card->mutex); in snd_soc_dpcm_runtime_update()
2630 int stream = fe_substream->stream; in dpcm_fe_dai_cleanup()
2634 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE; in dpcm_fe_dai_cleanup()
2638 fe->dpcm[stream].runtime = NULL; in dpcm_fe_dai_cleanup()
2646 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); in dpcm_fe_dai_close()
2651 mutex_unlock(&fe->card->mutex); in dpcm_fe_dai_close()
2660 int stream = fe_substream->stream; in dpcm_fe_dai_open()
2662 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME); in dpcm_fe_dai_open()
2663 fe->dpcm[stream].runtime = fe_substream->runtime; in dpcm_fe_dai_open()
2669 dev_dbg(fe->dev, "ASoC: %s no valid %s route\n", in dpcm_fe_dai_open()
2670 fe->dai_link->name, stream ? "capture" : "playback"); in dpcm_fe_dai_open()
2673 /* calculate valid and active FE <-> BE dpcms */ in dpcm_fe_dai_open()
2683 mutex_unlock(&fe->card->mutex); in dpcm_fe_dai_open()
2688 int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) in soc_new_pcm() argument
2699 if (rtd->dai_link->dynamic && rtd->num_cpus > 1) { in soc_new_pcm()
2700 dev_err(rtd->dev, in soc_new_pcm()
2701 "DPCM doesn't support Multi CPU for Front-Ends yet\n"); in soc_new_pcm()
2702 return -EINVAL; in soc_new_pcm()
2705 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { in soc_new_pcm()
2706 if (rtd->dai_link->dpcm_playback) { in soc_new_pcm()
2717 dev_err(rtd->card->dev, in soc_new_pcm()
2719 rtd->dai_link->stream_name); in soc_new_pcm()
2720 return -EINVAL; in soc_new_pcm()
2723 if (rtd->dai_link->dpcm_capture) { in soc_new_pcm()
2734 dev_err(rtd->card->dev, in soc_new_pcm()
2736 rtd->dai_link->stream_name); in soc_new_pcm()
2737 return -EINVAL; in soc_new_pcm()
2742 int cpu_capture = rtd->dai_link->params ? in soc_new_pcm()
2744 int cpu_playback = rtd->dai_link->params ? in soc_new_pcm()
2748 if (rtd->num_cpus == 1) { in soc_new_pcm()
2750 } else if (rtd->num_cpus == rtd->num_codecs) { in soc_new_pcm()
2753 dev_err(rtd->card->dev, in soc_new_pcm()
2755 return -EINVAL; in soc_new_pcm()
2767 if (rtd->dai_link->playback_only) { in soc_new_pcm()
2772 if (rtd->dai_link->capture_only) { in soc_new_pcm()
2778 if (rtd->dai_link->params) { in soc_new_pcm()
2780 rtd->dai_link->stream_name); in soc_new_pcm()
2782 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, in soc_new_pcm()
2784 } else if (rtd->dai_link->no_pcm) { in soc_new_pcm()
2786 rtd->dai_link->stream_name); in soc_new_pcm()
2788 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num, in soc_new_pcm()
2791 if (rtd->dai_link->dynamic) in soc_new_pcm()
2793 rtd->dai_link->stream_name); in soc_new_pcm()
2795 snprintf(new_name, sizeof(new_name), "%s %s-%d", in soc_new_pcm()
2796 rtd->dai_link->stream_name, in soc_new_pcm()
2797 (rtd->num_codecs > 1) ? in soc_new_pcm()
2798 "multicodec" : asoc_rtd_to_codec(rtd, 0)->name, num); in soc_new_pcm()
2800 ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback, in soc_new_pcm()
2804 dev_err(rtd->card->dev, "ASoC: can't create pcm %s for dailink %s: %d\n", in soc_new_pcm()
2805 new_name, rtd->dai_link->name, ret); in soc_new_pcm()
2808 dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name); in soc_new_pcm()
2811 if (rtd->dai_link->params) in soc_new_pcm()
2812 rtd->close_delayed_work_func = codec2codec_close_delayed_work; in soc_new_pcm()
2814 rtd->close_delayed_work_func = snd_soc_close_delayed_work; in soc_new_pcm()
2816 pcm->nonatomic = rtd->dai_link->nonatomic; in soc_new_pcm()
2817 rtd->pcm = pcm; in soc_new_pcm()
2818 pcm->private_data = rtd; in soc_new_pcm()
2820 if (rtd->dai_link->no_pcm || rtd->dai_link->params) { in soc_new_pcm()
2822 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd; in soc_new_pcm()
2824 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd; in soc_new_pcm()
2829 if (rtd->dai_link->dynamic) { in soc_new_pcm()
2830 rtd->ops.open = dpcm_fe_dai_open; in soc_new_pcm()
2831 rtd->ops.hw_params = dpcm_fe_dai_hw_params; in soc_new_pcm()
2832 rtd->ops.prepare = dpcm_fe_dai_prepare; in soc_new_pcm()
2833 rtd->ops.trigger = dpcm_fe_dai_trigger; in soc_new_pcm()
2834 rtd->ops.hw_free = dpcm_fe_dai_hw_free; in soc_new_pcm()
2835 rtd->ops.close = dpcm_fe_dai_close; in soc_new_pcm()
2836 rtd->ops.pointer = soc_pcm_pointer; in soc_new_pcm()
2838 rtd->ops.open = soc_pcm_open; in soc_new_pcm()
2839 rtd->ops.hw_params = soc_pcm_hw_params; in soc_new_pcm()
2840 rtd->ops.prepare = soc_pcm_prepare; in soc_new_pcm()
2841 rtd->ops.trigger = soc_pcm_trigger; in soc_new_pcm()
2842 rtd->ops.hw_free = soc_pcm_hw_free; in soc_new_pcm()
2843 rtd->ops.close = soc_pcm_close; in soc_new_pcm()
2844 rtd->ops.pointer = soc_pcm_pointer; in soc_new_pcm()
2848 const struct snd_soc_component_driver *drv = component->driver; in soc_new_pcm()
2850 if (drv->ioctl) in soc_new_pcm()
2851 rtd->ops.ioctl = snd_soc_pcm_component_ioctl; in soc_new_pcm()
2852 if (drv->sync_stop) in soc_new_pcm()
2853 rtd->ops.sync_stop = snd_soc_pcm_component_sync_stop; in soc_new_pcm()
2854 if (drv->copy_user) in soc_new_pcm()
2855 rtd->ops.copy_user = snd_soc_pcm_component_copy_user; in soc_new_pcm()
2856 if (drv->page) in soc_new_pcm()
2857 rtd->ops.page = snd_soc_pcm_component_page; in soc_new_pcm()
2858 if (drv->mmap) in soc_new_pcm()
2859 rtd->ops.mmap = snd_soc_pcm_component_mmap; in soc_new_pcm()
2863 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &rtd->ops); in soc_new_pcm()
2866 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops); in soc_new_pcm()
2870 dev_err(rtd->dev, "ASoC: pcm %s constructor failed for dailink %s: %d\n", in soc_new_pcm()
2871 new_name, rtd->dai_link->name, ret); in soc_new_pcm()
2875 pcm->no_device_suspend = true; in soc_new_pcm()
2877 dev_dbg(rtd->card->dev, "%s <-> %s mapping ok\n", in soc_new_pcm()
2878 (rtd->num_codecs > 1) ? "multicodec" : asoc_rtd_to_codec(rtd, 0)->name, in soc_new_pcm()
2879 (rtd->num_cpus > 1) ? "multicpu" : asoc_rtd_to_cpu(rtd, 0)->name); in soc_new_pcm()
2883 /* is the current PCM operation for this FE ? */
2886 if (fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) in snd_soc_dpcm_fe_can_update()
2892 /* is the current PCM operation for this BE ? */
2896 if ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) || in snd_soc_dpcm_be_can_update()
2897 ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_BE) && in snd_soc_dpcm_be_can_update()
2898 be->dpcm[stream].runtime_update)) in snd_soc_dpcm_be_can_update()
2908 return be->pcm->streams[stream].substream; in snd_soc_dpcm_get_substream()
2924 spin_lock_irqsave(&fe->card->dpcm_lock, flags); in snd_soc_dpcm_check_state()
2927 if (dpcm->fe == fe) in snd_soc_dpcm_check_state()
2930 state = dpcm->fe->dpcm[stream].state; in snd_soc_dpcm_check_state()
2938 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags); in snd_soc_dpcm_check_state()