Merge series "ASoC: soc-pcm cleanup step6" from Kuninori Morimoto <kuninori.morimoto...
[linux-block.git] / sound / soc / soc-pcm.c
CommitLineData
ed517582
KM
1// SPDX-License-Identifier: GPL-2.0+
2//
3// soc-pcm.c -- ALSA SoC PCM
4//
5// Copyright 2005 Wolfson Microelectronics PLC.
6// Copyright 2005 Openedhand Ltd.
7// Copyright (C) 2010 Slimlogic Ltd.
8// Copyright (C) 2010 Texas Instruments Inc.
9//
10// Authors: Liam Girdwood <lrg@ti.com>
11// Mark Brown <broonie@opensource.wolfsonmicro.com>
ddee627c
LG
12
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/delay.h>
988e8cc4 16#include <linux/pinctrl/consumer.h>
d6652ef8 17#include <linux/pm_runtime.h>
ddee627c
LG
18#include <linux/slab.h>
19#include <linux/workqueue.h>
01d7584c 20#include <linux/export.h>
f86dcef8 21#include <linux/debugfs.h>
ddee627c
LG
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
01d7584c 26#include <sound/soc-dpcm.h>
ddee627c
LG
27#include <sound/initval.h>
28
01d7584c
LG
29#define DPCM_MAX_BE_USERS 8
30
c3212829
KM
31#ifdef CONFIG_DEBUG_FS
32static const char *dpcm_state_string(enum snd_soc_dpcm_state state)
33{
34 switch (state) {
35 case SND_SOC_DPCM_STATE_NEW:
36 return "new";
37 case SND_SOC_DPCM_STATE_OPEN:
38 return "open";
39 case SND_SOC_DPCM_STATE_HW_PARAMS:
40 return "hw_params";
41 case SND_SOC_DPCM_STATE_PREPARE:
42 return "prepare";
43 case SND_SOC_DPCM_STATE_START:
44 return "start";
45 case SND_SOC_DPCM_STATE_STOP:
46 return "stop";
47 case SND_SOC_DPCM_STATE_SUSPEND:
48 return "suspend";
49 case SND_SOC_DPCM_STATE_PAUSED:
50 return "paused";
51 case SND_SOC_DPCM_STATE_HW_FREE:
52 return "hw_free";
53 case SND_SOC_DPCM_STATE_CLOSE:
54 return "close";
55 }
56
57 return "unknown";
58}
59
60static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe,
61 int stream, char *buf, size_t size)
62{
63 struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params;
64 struct snd_soc_dpcm *dpcm;
65 ssize_t offset = 0;
66 unsigned long flags;
67
68 /* FE state */
69 offset += snprintf(buf + offset, size - offset,
70 "[%s - %s]\n", fe->dai_link->name,
71 stream ? "Capture" : "Playback");
72
73 offset += snprintf(buf + offset, size - offset, "State: %s\n",
74 dpcm_state_string(fe->dpcm[stream].state));
75
76 if ((fe->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) &&
77 (fe->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP))
78 offset += snprintf(buf + offset, size - offset,
79 "Hardware Params: "
80 "Format = %s, Channels = %d, Rate = %d\n",
81 snd_pcm_format_name(params_format(params)),
82 params_channels(params),
83 params_rate(params));
84
85 /* BEs state */
86 offset += snprintf(buf + offset, size - offset, "Backends:\n");
87
88 if (list_empty(&fe->dpcm[stream].be_clients)) {
89 offset += snprintf(buf + offset, size - offset,
90 " No active DSP links\n");
91 goto out;
92 }
93
94 spin_lock_irqsave(&fe->card->dpcm_lock, flags);
95 for_each_dpcm_be(fe, stream, dpcm) {
96 struct snd_soc_pcm_runtime *be = dpcm->be;
97 params = &dpcm->hw_params;
98
99 offset += snprintf(buf + offset, size - offset,
100 "- %s\n", be->dai_link->name);
101
102 offset += snprintf(buf + offset, size - offset,
103 " State: %s\n",
104 dpcm_state_string(be->dpcm[stream].state));
105
106 if ((be->dpcm[stream].state >= SND_SOC_DPCM_STATE_HW_PARAMS) &&
107 (be->dpcm[stream].state <= SND_SOC_DPCM_STATE_STOP))
108 offset += snprintf(buf + offset, size - offset,
109 " Hardware Params: "
110 "Format = %s, Channels = %d, Rate = %d\n",
111 snd_pcm_format_name(params_format(params)),
112 params_channels(params),
113 params_rate(params));
114 }
115 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
116out:
117 return offset;
118}
119
120static ssize_t dpcm_state_read_file(struct file *file, char __user *user_buf,
121 size_t count, loff_t *ppos)
122{
123 struct snd_soc_pcm_runtime *fe = file->private_data;
124 ssize_t out_count = PAGE_SIZE, offset = 0, ret = 0;
125 int stream;
126 char *buf;
127
6e1276a5
BL
128 if (fe->num_cpus > 1) {
129 dev_err(fe->dev,
130 "%s doesn't support Multi CPU yet\n", __func__);
131 return -EINVAL;
132 }
133
c3212829
KM
134 buf = kmalloc(out_count, GFP_KERNEL);
135 if (!buf)
136 return -ENOMEM;
137
138 for_each_pcm_streams(stream)
139 if (snd_soc_dai_stream_valid(fe->cpu_dai, stream))
140 offset += dpcm_show_state(fe, stream,
141 buf + offset,
142 out_count - offset);
143
144 ret = simple_read_from_buffer(user_buf, count, ppos, buf, offset);
145
146 kfree(buf);
147 return ret;
148}
149
150static const struct file_operations dpcm_state_fops = {
151 .open = simple_open,
152 .read = dpcm_state_read_file,
153 .llseek = default_llseek,
154};
155
156void soc_dpcm_debugfs_add(struct snd_soc_pcm_runtime *rtd)
157{
158 if (!rtd->dai_link)
159 return;
160
161 if (!rtd->dai_link->dynamic)
162 return;
163
164 if (!rtd->card->debugfs_card_root)
165 return;
166
167 rtd->debugfs_dpcm_root = debugfs_create_dir(rtd->dai_link->name,
168 rtd->card->debugfs_card_root);
169
170 debugfs_create_file("state", 0444, rtd->debugfs_dpcm_root,
171 rtd, &dpcm_state_fops);
172}
154dae87
KM
173
174static void dpcm_create_debugfs_state(struct snd_soc_dpcm *dpcm, int stream)
175{
176 char *name;
177
178 name = kasprintf(GFP_KERNEL, "%s:%s", dpcm->be->dai_link->name,
179 stream ? "capture" : "playback");
180 if (name) {
181 dpcm->debugfs_state = debugfs_create_dir(
182 name, dpcm->fe->debugfs_dpcm_root);
183 debugfs_create_u32("state", 0644, dpcm->debugfs_state,
184 &dpcm->state);
185 kfree(name);
186 }
187}
188
189static void dpcm_remove_debugfs_state(struct snd_soc_dpcm *dpcm)
190{
191 debugfs_remove_recursive(dpcm->debugfs_state);
192}
193
194#else
195static inline void dpcm_create_debugfs_state(struct snd_soc_dpcm *dpcm,
196 int stream)
197{
198}
199
200static inline void dpcm_remove_debugfs_state(struct snd_soc_dpcm *dpcm)
201{
202}
c3212829
KM
203#endif
204
f183f927
KM
205static int soc_rtd_startup(struct snd_soc_pcm_runtime *rtd,
206 struct snd_pcm_substream *substream)
207{
208 if (rtd->dai_link->ops &&
209 rtd->dai_link->ops->startup)
210 return rtd->dai_link->ops->startup(substream);
211 return 0;
212}
213
0be429f9
KM
214static void soc_rtd_shutdown(struct snd_soc_pcm_runtime *rtd,
215 struct snd_pcm_substream *substream)
216{
217 if (rtd->dai_link->ops &&
218 rtd->dai_link->ops->shutdown)
219 rtd->dai_link->ops->shutdown(substream);
220}
221
44c1a75b
KM
222static int soc_rtd_prepare(struct snd_soc_pcm_runtime *rtd,
223 struct snd_pcm_substream *substream)
224{
225 if (rtd->dai_link->ops &&
226 rtd->dai_link->ops->prepare)
227 return rtd->dai_link->ops->prepare(substream);
228 return 0;
229}
230
de9ad990
KM
231static int soc_rtd_hw_params(struct snd_soc_pcm_runtime *rtd,
232 struct snd_pcm_substream *substream,
233 struct snd_pcm_hw_params *params)
234{
235 if (rtd->dai_link->ops &&
236 rtd->dai_link->ops->hw_params)
237 return rtd->dai_link->ops->hw_params(substream, params);
238 return 0;
239}
240
49f020e5
KM
241static void soc_rtd_hw_free(struct snd_soc_pcm_runtime *rtd,
242 struct snd_pcm_substream *substream)
243{
244 if (rtd->dai_link->ops &&
245 rtd->dai_link->ops->hw_free)
246 rtd->dai_link->ops->hw_free(substream);
247}
248
ad2bf9f2
KM
249static int soc_rtd_trigger(struct snd_soc_pcm_runtime *rtd,
250 struct snd_pcm_substream *substream,
251 int cmd)
252{
253 if (rtd->dai_link->ops &&
254 rtd->dai_link->ops->trigger)
255 return rtd->dai_link->ops->trigger(substream, cmd);
256 return 0;
257}
258
7a5aaba4
KM
259static void snd_soc_runtime_action(struct snd_soc_pcm_runtime *rtd,
260 int stream, int action)
24894b76 261{
19bdcc7a 262 struct snd_soc_dai *cpu_dai;
0b7990e3 263 struct snd_soc_dai *codec_dai;
2e5894d7 264 int i;
24894b76 265
72b745e3 266 lockdep_assert_held(&rtd->card->pcm_mutex);
24894b76 267
a4be4187 268 for_each_rtd_cpu_dais(rtd, i, cpu_dai)
19bdcc7a
SN
269 cpu_dai->stream_active[stream] += action;
270
a4be4187 271 for_each_rtd_codec_dais(rtd, i, codec_dai)
0f6011fd 272 codec_dai->stream_active[stream] += action;
24894b76 273
a4be4187 274 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
275 cpu_dai->active += action;
276 cpu_dai->component->active += action;
277 }
a4be4187 278 for_each_rtd_codec_dais(rtd, i, codec_dai) {
7a5aaba4
KM
279 codec_dai->active += action;
280 codec_dai->component->active += action;
2e5894d7 281 }
24894b76
LPC
282}
283
7a5aaba4
KM
284/**
285 * snd_soc_runtime_activate() - Increment active count for PCM runtime components
286 * @rtd: ASoC PCM runtime that is activated
287 * @stream: Direction of the PCM stream
288 *
289 * Increments the active count for all the DAIs and components attached to a PCM
290 * runtime. Should typically be called when a stream is opened.
291 *
292 * Must be called with the rtd->card->pcm_mutex being held
293 */
294void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
295{
296 snd_soc_runtime_action(rtd, stream, 1);
297}
298
24894b76
LPC
299/**
300 * snd_soc_runtime_deactivate() - Decrement active count for PCM runtime components
301 * @rtd: ASoC PCM runtime that is deactivated
302 * @stream: Direction of the PCM stream
303 *
304 * Decrements the active count for all the DAIs and components attached to a PCM
305 * runtime. Should typically be called when a stream is closed.
306 *
72b745e3 307 * Must be called with the rtd->card->pcm_mutex being held
24894b76
LPC
308 */
309void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
310{
7a5aaba4 311 snd_soc_runtime_action(rtd, stream, -1);
24894b76
LPC
312}
313
208a1589
LPC
314/**
315 * snd_soc_runtime_ignore_pmdown_time() - Check whether to ignore the power down delay
316 * @rtd: The ASoC PCM runtime that should be checked.
317 *
318 * This function checks whether the power down delay should be ignored for a
319 * specific PCM runtime. Returns true if the delay is 0, if it the DAI link has
320 * been configured to ignore the delay, or if none of the components benefits
321 * from having the delay.
322 */
323bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd)
324{
fbb16563 325 struct snd_soc_component *component;
2e5894d7 326 bool ignore = true;
613fb500 327 int i;
2e5894d7 328
208a1589
LPC
329 if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time)
330 return true;
331
613fb500 332 for_each_rtd_components(rtd, i, component)
72c38184 333 ignore &= !component->driver->use_pmdown_time;
fbb16563 334
fbb16563 335 return ignore;
208a1589
LPC
336}
337
90996f43
LPC
338/**
339 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
340 * @substream: the pcm substream
341 * @hw: the hardware parameters
342 *
343 * Sets the substream runtime hardware parameters.
344 */
345int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
346 const struct snd_pcm_hardware *hw)
347{
348 struct snd_pcm_runtime *runtime = substream->runtime;
349 runtime->hw.info = hw->info;
350 runtime->hw.formats = hw->formats;
351 runtime->hw.period_bytes_min = hw->period_bytes_min;
352 runtime->hw.period_bytes_max = hw->period_bytes_max;
353 runtime->hw.periods_min = hw->periods_min;
354 runtime->hw.periods_max = hw->periods_max;
355 runtime->hw.buffer_bytes_max = hw->buffer_bytes_max;
356 runtime->hw.fifo_size = hw->fifo_size;
357 return 0;
358}
359EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
360
01d7584c 361/* DPCM stream event, send event to FE and all active BEs. */
23607025 362int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
01d7584c
LG
363 int event)
364{
365 struct snd_soc_dpcm *dpcm;
366
8d6258a4 367 for_each_dpcm_be(fe, dir, dpcm) {
01d7584c
LG
368
369 struct snd_soc_pcm_runtime *be = dpcm->be;
370
103d84a3 371 dev_dbg(be->dev, "ASoC: BE %s event %d dir %d\n",
01d7584c
LG
372 be->dai_link->name, event, dir);
373
b1cd2e34
BG
374 if ((event == SND_SOC_DAPM_STREAM_STOP) &&
375 (be->dpcm[dir].users >= 1))
376 continue;
377
01d7584c
LG
378 snd_soc_dapm_stream_event(be, dir, event);
379 }
380
381 snd_soc_dapm_stream_event(fe, dir, event);
382
383 return 0;
384}
385
17841020
DA
386static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
387 struct snd_soc_dai *soc_dai)
ddee627c
LG
388{
389 struct snd_soc_pcm_runtime *rtd = substream->private_data;
ddee627c
LG
390 int ret;
391
3635bf09
NC
392 if (soc_dai->rate && (soc_dai->driver->symmetric_rates ||
393 rtd->dai_link->symmetric_rates)) {
394 dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %dHz rate\n",
395 soc_dai->rate);
396
4dcdd43b 397 ret = snd_pcm_hw_constraint_single(substream->runtime,
3635bf09 398 SNDRV_PCM_HW_PARAM_RATE,
4dcdd43b 399 soc_dai->rate);
3635bf09
NC
400 if (ret < 0) {
401 dev_err(soc_dai->dev,
402 "ASoC: Unable to apply rate constraint: %d\n",
403 ret);
404 return ret;
405 }
406 }
ddee627c 407
3635bf09
NC
408 if (soc_dai->channels && (soc_dai->driver->symmetric_channels ||
409 rtd->dai_link->symmetric_channels)) {
410 dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d channel(s)\n",
411 soc_dai->channels);
ddee627c 412
4dcdd43b 413 ret = snd_pcm_hw_constraint_single(substream->runtime,
3635bf09 414 SNDRV_PCM_HW_PARAM_CHANNELS,
3635bf09
NC
415 soc_dai->channels);
416 if (ret < 0) {
417 dev_err(soc_dai->dev,
418 "ASoC: Unable to apply channel symmetry constraint: %d\n",
419 ret);
420 return ret;
421 }
ddee627c
LG
422 }
423
3635bf09
NC
424 if (soc_dai->sample_bits && (soc_dai->driver->symmetric_samplebits ||
425 rtd->dai_link->symmetric_samplebits)) {
426 dev_dbg(soc_dai->dev, "ASoC: Symmetry forces %d sample bits\n",
427 soc_dai->sample_bits);
ddee627c 428
4dcdd43b 429 ret = snd_pcm_hw_constraint_single(substream->runtime,
3635bf09 430 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
3635bf09
NC
431 soc_dai->sample_bits);
432 if (ret < 0) {
433 dev_err(soc_dai->dev,
434 "ASoC: Unable to apply sample bits symmetry constraint: %d\n",
435 ret);
436 return ret;
437 }
ddee627c
LG
438 }
439
440 return 0;
441}
442
3635bf09
NC
443static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream,
444 struct snd_pcm_hw_params *params)
445{
446 struct snd_soc_pcm_runtime *rtd = substream->private_data;
19bdcc7a 447 struct snd_soc_dai *cpu_dai;
0b7990e3 448 struct snd_soc_dai *codec_dai;
2e5894d7 449 unsigned int rate, channels, sample_bits, symmetry, i;
3635bf09
NC
450
451 rate = params_rate(params);
452 channels = params_channels(params);
453 sample_bits = snd_pcm_format_physical_width(params_format(params));
454
455 /* reject unmatched parameters when applying symmetry */
19bdcc7a
SN
456 symmetry = rtd->dai_link->symmetric_rates;
457
a4be4187 458 for_each_rtd_cpu_dais(rtd, i, cpu_dai)
19bdcc7a 459 symmetry |= cpu_dai->driver->symmetric_rates;
2e5894d7 460
a4be4187 461 for_each_rtd_codec_dais(rtd, i, codec_dai)
0b7990e3 462 symmetry |= codec_dai->driver->symmetric_rates;
2e5894d7 463
19bdcc7a 464 if (symmetry) {
a4be4187 465 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
466 if (cpu_dai->rate && cpu_dai->rate != rate) {
467 dev_err(rtd->dev, "ASoC: unmatched rate symmetry: %d - %d\n",
468 cpu_dai->rate, rate);
469 return -EINVAL;
470 }
471 }
ddee627c
LG
472 }
473
19bdcc7a
SN
474 symmetry = rtd->dai_link->symmetric_channels;
475
a4be4187 476 for_each_rtd_cpu_dais(rtd, i, cpu_dai)
19bdcc7a 477 symmetry |= cpu_dai->driver->symmetric_channels;
2e5894d7 478
a4be4187 479 for_each_rtd_codec_dais(rtd, i, codec_dai)
0b7990e3 480 symmetry |= codec_dai->driver->symmetric_channels;
2e5894d7 481
19bdcc7a 482 if (symmetry) {
a4be4187 483 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
484 if (cpu_dai->channels &&
485 cpu_dai->channels != channels) {
486 dev_err(rtd->dev, "ASoC: unmatched channel symmetry: %d - %d\n",
487 cpu_dai->channels, channels);
488 return -EINVAL;
489 }
490 }
3635bf09 491 }
ddee627c 492
19bdcc7a
SN
493 symmetry = rtd->dai_link->symmetric_samplebits;
494
a4be4187 495 for_each_rtd_cpu_dais(rtd, i, cpu_dai)
19bdcc7a 496 symmetry |= cpu_dai->driver->symmetric_samplebits;
2e5894d7 497
a4be4187 498 for_each_rtd_codec_dais(rtd, i, codec_dai)
0b7990e3 499 symmetry |= codec_dai->driver->symmetric_samplebits;
2e5894d7 500
19bdcc7a 501 if (symmetry) {
a4be4187 502 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
503 if (cpu_dai->sample_bits &&
504 cpu_dai->sample_bits != sample_bits) {
505 dev_err(rtd->dev, "ASoC: unmatched sample bits symmetry: %d - %d\n",
506 cpu_dai->sample_bits, sample_bits);
507 return -EINVAL;
508 }
509 }
ddee627c
LG
510 }
511
512 return 0;
513}
514
62e5f676
LPC
515static bool soc_pcm_has_symmetry(struct snd_pcm_substream *substream)
516{
517 struct snd_soc_pcm_runtime *rtd = substream->private_data;
62e5f676 518 struct snd_soc_dai_link *link = rtd->dai_link;
0b7990e3 519 struct snd_soc_dai *codec_dai;
19bdcc7a 520 struct snd_soc_dai *cpu_dai;
2e5894d7 521 unsigned int symmetry, i;
62e5f676 522
19bdcc7a
SN
523 symmetry = link->symmetric_rates ||
524 link->symmetric_channels ||
525 link->symmetric_samplebits;
526
a4be4187 527 for_each_rtd_cpu_dais(rtd, i, cpu_dai)
19bdcc7a
SN
528 symmetry = symmetry ||
529 cpu_dai->driver->symmetric_rates ||
530 cpu_dai->driver->symmetric_channels ||
531 cpu_dai->driver->symmetric_samplebits;
62e5f676 532
a4be4187 533 for_each_rtd_codec_dais(rtd, i, codec_dai)
2e5894d7 534 symmetry = symmetry ||
0b7990e3
KM
535 codec_dai->driver->symmetric_rates ||
536 codec_dai->driver->symmetric_channels ||
537 codec_dai->driver->symmetric_samplebits;
2e5894d7
BC
538
539 return symmetry;
62e5f676
LPC
540}
541
2e5894d7 542static void soc_pcm_set_msb(struct snd_pcm_substream *substream, int bits)
58ba9b25 543{
2e5894d7 544 struct snd_soc_pcm_runtime *rtd = substream->private_data;
c6068d3a 545 int ret;
58ba9b25
MB
546
547 if (!bits)
548 return;
549
0e2a3751
LPC
550 ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 0, bits);
551 if (ret != 0)
552 dev_warn(rtd->dev, "ASoC: Failed to set MSB %d: %d\n",
553 bits, ret);
58ba9b25
MB
554}
555
c8dd1fec
BC
556static void soc_pcm_apply_msb(struct snd_pcm_substream *substream)
557{
558 struct snd_soc_pcm_runtime *rtd = substream->private_data;
19bdcc7a 559 struct snd_soc_dai *cpu_dai;
2e5894d7 560 struct snd_soc_dai *codec_dai;
57be9206
KM
561 struct snd_soc_pcm_stream *pcm_codec, *pcm_cpu;
562 int stream = substream->stream;
2e5894d7 563 int i;
19bdcc7a 564 unsigned int bits = 0, cpu_bits = 0;
c8dd1fec 565
a4be4187 566 for_each_rtd_codec_dais(rtd, i, codec_dai) {
57be9206
KM
567 pcm_codec = snd_soc_dai_get_pcm_stream(codec_dai, stream);
568
569 if (pcm_codec->sig_bits == 0) {
570 bits = 0;
571 break;
2e5894d7 572 }
57be9206 573 bits = max(pcm_codec->sig_bits, bits);
c8dd1fec
BC
574 }
575
a4be4187 576 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
577 pcm_cpu = snd_soc_dai_get_pcm_stream(cpu_dai, stream);
578
579 if (pcm_cpu->sig_bits == 0) {
580 cpu_bits = 0;
581 break;
582 }
583 cpu_bits = max(pcm_cpu->sig_bits, cpu_bits);
584 }
57be9206 585
2e5894d7
BC
586 soc_pcm_set_msb(substream, bits);
587 soc_pcm_set_msb(substream, cpu_bits);
c8dd1fec
BC
588}
589
5854a464
SH
590/**
591 * snd_soc_runtime_calc_hw() - Calculate hw limits for a PCM stream
592 * @rtd: ASoC PCM runtime
593 * @hw: PCM hardware parameters (output)
594 * @stream: Direction of the PCM stream
595 *
596 * Calculates the subset of stream parameters supported by all DAIs
597 * associated with the PCM stream.
598 */
599int snd_soc_runtime_calc_hw(struct snd_soc_pcm_runtime *rtd,
600 struct snd_pcm_hardware *hw, int stream)
bd477c31 601{
0b7990e3 602 struct snd_soc_dai *codec_dai;
19bdcc7a 603 struct snd_soc_dai *cpu_dai;
2e5894d7
BC
604 struct snd_soc_pcm_stream *codec_stream;
605 struct snd_soc_pcm_stream *cpu_stream;
606 unsigned int chan_min = 0, chan_max = UINT_MAX;
19bdcc7a 607 unsigned int cpu_chan_min = 0, cpu_chan_max = UINT_MAX;
2e5894d7 608 unsigned int rate_min = 0, rate_max = UINT_MAX;
19bdcc7a
SN
609 unsigned int cpu_rate_min = 0, cpu_rate_max = UINT_MAX;
610 unsigned int rates = UINT_MAX, cpu_rates = UINT_MAX;
2e5894d7
BC
611 u64 formats = ULLONG_MAX;
612 int i;
78e45c99 613
19bdcc7a 614 /* first calculate min/max only for CPUs in the DAI link */
a4be4187 615 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
0e9cf4c4
BL
616
617 /*
618 * Skip CPUs which don't support the current stream type.
619 * Otherwise, since the rate, channel, and format values will
620 * zero in that case, we would have no usable settings left,
621 * causing the resulting setup to fail.
0e9cf4c4 622 */
5854a464 623 if (!snd_soc_dai_stream_valid(cpu_dai, stream))
0e9cf4c4
BL
624 continue;
625
19bdcc7a
SN
626 cpu_stream = snd_soc_dai_get_pcm_stream(cpu_dai, stream);
627
628 cpu_chan_min = max(cpu_chan_min, cpu_stream->channels_min);
629 cpu_chan_max = min(cpu_chan_max, cpu_stream->channels_max);
630 cpu_rate_min = max(cpu_rate_min, cpu_stream->rate_min);
631 cpu_rate_max = min_not_zero(cpu_rate_max, cpu_stream->rate_max);
632 formats &= cpu_stream->formats;
633 cpu_rates = snd_pcm_rate_mask_intersect(cpu_stream->rates,
634 cpu_rates);
635 }
78e45c99 636
19bdcc7a 637 /* second calculate min/max only for CODECs in the DAI link */
a4be4187 638 for_each_rtd_codec_dais(rtd, i, codec_dai) {
cde79035
RW
639
640 /*
641 * Skip CODECs which don't support the current stream type.
642 * Otherwise, since the rate, channel, and format values will
643 * zero in that case, we would have no usable settings left,
644 * causing the resulting setup to fail.
cde79035 645 */
25c2f515 646 if (!snd_soc_dai_stream_valid(codec_dai, stream))
cde79035
RW
647 continue;
648
acf253c1
KM
649 codec_stream = snd_soc_dai_get_pcm_stream(codec_dai, stream);
650
2e5894d7
BC
651 chan_min = max(chan_min, codec_stream->channels_min);
652 chan_max = min(chan_max, codec_stream->channels_max);
653 rate_min = max(rate_min, codec_stream->rate_min);
654 rate_max = min_not_zero(rate_max, codec_stream->rate_max);
655 formats &= codec_stream->formats;
656 rates = snd_pcm_rate_mask_intersect(codec_stream->rates, rates);
657 }
658
5854a464
SH
659 /* Verify both a valid CPU DAI and a valid CODEC DAI were found */
660 if (!chan_min || !cpu_chan_min)
661 return -EINVAL;
662
2e5894d7
BC
663 /*
664 * chan min/max cannot be enforced if there are multiple CODEC DAIs
19bdcc7a 665 * connected to CPU DAI(s), use CPU DAI's directly and let
2e5894d7
BC
666 * channel allocation be fixed up later
667 */
668 if (rtd->num_codecs > 1) {
19bdcc7a
SN
669 chan_min = cpu_chan_min;
670 chan_max = cpu_chan_max;
2e5894d7
BC
671 }
672
19bdcc7a
SN
673 /* finally find a intersection between CODECs and CPUs */
674 hw->channels_min = max(chan_min, cpu_chan_min);
675 hw->channels_max = min(chan_max, cpu_chan_max);
5854a464 676 hw->formats = formats;
19bdcc7a 677 hw->rates = snd_pcm_rate_mask_intersect(rates, cpu_rates);
78e45c99 678
5854a464 679 snd_pcm_hw_limit_rates(hw);
78e45c99 680
19bdcc7a 681 hw->rate_min = max(hw->rate_min, cpu_rate_min);
2e5894d7 682 hw->rate_min = max(hw->rate_min, rate_min);
19bdcc7a 683 hw->rate_max = min_not_zero(hw->rate_max, cpu_rate_max);
2e5894d7 684 hw->rate_max = min_not_zero(hw->rate_max, rate_max);
5854a464
SH
685
686 return 0;
687}
688EXPORT_SYMBOL_GPL(snd_soc_runtime_calc_hw);
689
690static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
691{
692 struct snd_pcm_hardware *hw = &substream->runtime->hw;
693 struct snd_soc_pcm_runtime *rtd = substream->private_data;
694 u64 formats = hw->formats;
695
696 /*
697 * At least one CPU and one CODEC should match. Otherwise, we should
698 * have bailed out on a higher level, since there would be no CPU or
699 * CODEC to support the transfer direction in that case.
700 */
701 snd_soc_runtime_calc_hw(rtd, hw, substream->stream);
702
703 if (formats)
704 hw->formats &= formats;
bd477c31
LPC
705}
706
dd03907b 707static int soc_pcm_components_open(struct snd_pcm_substream *substream)
e7ecfdb7
KM
708{
709 struct snd_soc_pcm_runtime *rtd = substream->private_data;
d2aaa8d8 710 struct snd_soc_component *last = NULL;
e7ecfdb7 711 struct snd_soc_component *component;
613fb500 712 int i, ret = 0;
e7ecfdb7 713
613fb500 714 for_each_rtd_components(rtd, i, component) {
d2aaa8d8
KV
715 last = component;
716
4a81e8f3
KM
717 ret = snd_soc_component_module_get_when_open(component);
718 if (ret < 0) {
e7ecfdb7
KM
719 dev_err(component->dev,
720 "ASoC: can't get module %s\n",
721 component->name);
d2aaa8d8 722 break;
e7ecfdb7
KM
723 }
724
ae2f4849 725 ret = snd_soc_component_open(component, substream);
e7ecfdb7 726 if (ret < 0) {
d2aaa8d8 727 snd_soc_component_module_put_when_close(component);
e7ecfdb7
KM
728 dev_err(component->dev,
729 "ASoC: can't open component %s: %d\n",
730 component->name, ret);
d2aaa8d8 731 break;
e7ecfdb7
KM
732 }
733 }
dd03907b 734
d2aaa8d8
KV
735 if (ret < 0) {
736 /* rollback on error */
737 for_each_rtd_components(rtd, i, component) {
738 if (component == last)
739 break;
740
741 snd_soc_component_close(component, substream);
742 snd_soc_component_module_put_when_close(component);
743 }
744 }
745
746 return ret;
e7ecfdb7
KM
747}
748
dd03907b 749static int soc_pcm_components_close(struct snd_pcm_substream *substream)
244e2936
CK
750{
751 struct snd_soc_pcm_runtime *rtd = substream->private_data;
244e2936 752 struct snd_soc_component *component;
e82ebffc 753 int i, r, ret = 0;
244e2936 754
613fb500 755 for_each_rtd_components(rtd, i, component) {
e82ebffc
KM
756 r = snd_soc_component_close(component, substream);
757 if (r < 0)
758 ret = r; /* use last ret */
759
4a81e8f3 760 snd_soc_component_module_put_when_close(component);
244e2936
CK
761 }
762
3672beb8 763 return ret;
244e2936
CK
764}
765
62c86d1d
KM
766/*
767 * Called by ALSA when a PCM substream is closed. Private data can be
768 * freed here. The cpu DAI, codec DAI, machine and components are also
769 * shutdown.
770 */
771static int soc_pcm_close(struct snd_pcm_substream *substream)
772{
773 struct snd_soc_pcm_runtime *rtd = substream->private_data;
774 struct snd_soc_component *component;
19bdcc7a 775 struct snd_soc_dai *cpu_dai;
62c86d1d
KM
776 struct snd_soc_dai *codec_dai;
777 int i;
778
779 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
780
781 snd_soc_runtime_deactivate(rtd, substream->stream);
782
a4be4187 783 for_each_rtd_cpu_dais(rtd, i, cpu_dai)
19bdcc7a 784 snd_soc_dai_shutdown(cpu_dai, substream);
62c86d1d 785
a4be4187 786 for_each_rtd_codec_dais(rtd, i, codec_dai)
62c86d1d
KM
787 snd_soc_dai_shutdown(codec_dai, substream);
788
789 soc_rtd_shutdown(rtd, substream);
790
791 soc_pcm_components_close(substream);
792
793 snd_soc_dapm_stream_stop(rtd, substream->stream);
794
795 mutex_unlock(&rtd->card->pcm_mutex);
796
797 for_each_rtd_components(rtd, i, component) {
798 pm_runtime_mark_last_busy(component->dev);
799 pm_runtime_put_autosuspend(component->dev);
800 }
801
802 for_each_rtd_components(rtd, i, component)
803 if (!component->active)
804 pinctrl_pm_select_sleep_state(component->dev);
805
806 return 0;
807}
808
ddee627c
LG
809/*
810 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
811 * then initialized and any private data can be allocated. This also calls
ef050bec 812 * startup for the cpu DAI, component, machine and codec DAI.
ddee627c
LG
813 */
814static int soc_pcm_open(struct snd_pcm_substream *substream)
815{
816 struct snd_soc_pcm_runtime *rtd = substream->private_data;
817 struct snd_pcm_runtime *runtime = substream->runtime;
90be711e 818 struct snd_soc_component *component;
19bdcc7a 819 struct snd_soc_dai *cpu_dai;
2e5894d7
BC
820 struct snd_soc_dai *codec_dai;
821 const char *codec_dai_name = "multicodec";
19bdcc7a 822 const char *cpu_dai_name = "multicpu";
244e2936 823 int i, ret = 0;
ddee627c 824
76c39e86
KM
825 for_each_rtd_components(rtd, i, component)
826 pinctrl_pm_select_default_state(component->dev);
90be711e 827
613fb500 828 for_each_rtd_components(rtd, i, component)
90be711e 829 pm_runtime_get_sync(component->dev);
d6652ef8 830
72b745e3 831 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
ddee627c 832
5d9fa03e
KM
833 ret = soc_pcm_components_open(substream);
834 if (ret < 0)
835 goto component_err;
836
837 ret = soc_rtd_startup(rtd, substream);
838 if (ret < 0) {
839 pr_err("ASoC: %s startup failed: %d\n",
840 rtd->dai_link->name, ret);
d2aaa8d8 841 goto rtd_startup_err;
5d9fa03e
KM
842 }
843
ddee627c 844 /* startup the audio subsystem */
a4be4187 845 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
846 ret = snd_soc_dai_startup(cpu_dai, substream);
847 if (ret < 0) {
848 dev_err(cpu_dai->dev, "ASoC: can't open interface %s: %d\n",
849 cpu_dai->name, ret);
850 goto cpu_dai_err;
851 }
ddee627c
LG
852 }
853
a4be4187 854 for_each_rtd_codec_dais(rtd, i, codec_dai) {
5a52a045
KM
855 ret = snd_soc_dai_startup(codec_dai, substream);
856 if (ret < 0) {
857 dev_err(codec_dai->dev,
858 "ASoC: can't open codec %s: %d\n",
859 codec_dai->name, ret);
5d9fa03e 860 goto config_err;
ddee627c 861 }
2e5894d7
BC
862
863 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
864 codec_dai->tx_mask = 0;
865 else
866 codec_dai->rx_mask = 0;
ddee627c
LG
867 }
868
01d7584c
LG
869 /* Dynamic PCM DAI links compat checks use dynamic capabilities */
870 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm)
871 goto dynamic;
872
ddee627c 873 /* Check that the codec and cpu DAIs are compatible */
2e5894d7
BC
874 soc_pcm_init_runtime_hw(substream);
875
876 if (rtd->num_codecs == 1)
877 codec_dai_name = rtd->codec_dai->name;
ddee627c 878
19bdcc7a
SN
879 if (rtd->num_cpus == 1)
880 cpu_dai_name = rtd->cpu_dai->name;
881
62e5f676
LPC
882 if (soc_pcm_has_symmetry(substream))
883 runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;
884
ddee627c 885 ret = -EINVAL;
ddee627c 886 if (!runtime->hw.rates) {
103d84a3 887 printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n",
19bdcc7a 888 codec_dai_name, cpu_dai_name);
ddee627c
LG
889 goto config_err;
890 }
891 if (!runtime->hw.formats) {
103d84a3 892 printk(KERN_ERR "ASoC: %s <-> %s No matching formats\n",
19bdcc7a 893 codec_dai_name, cpu_dai_name);
ddee627c
LG
894 goto config_err;
895 }
896 if (!runtime->hw.channels_min || !runtime->hw.channels_max ||
897 runtime->hw.channels_min > runtime->hw.channels_max) {
103d84a3 898 printk(KERN_ERR "ASoC: %s <-> %s No matching channels\n",
19bdcc7a 899 codec_dai_name, cpu_dai_name);
ddee627c
LG
900 goto config_err;
901 }
902
c8dd1fec 903 soc_pcm_apply_msb(substream);
58ba9b25 904
ddee627c 905 /* Symmetry only applies if we've already got an active stream. */
a4be4187 906 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
907 if (cpu_dai->active) {
908 ret = soc_pcm_apply_symmetry(substream, cpu_dai);
909 if (ret != 0)
910 goto config_err;
911 }
17841020
DA
912 }
913
a4be4187 914 for_each_rtd_codec_dais(rtd, i, codec_dai) {
0b7990e3
KM
915 if (codec_dai->active) {
916 ret = soc_pcm_apply_symmetry(substream, codec_dai);
2e5894d7
BC
917 if (ret != 0)
918 goto config_err;
919 }
ddee627c
LG
920 }
921
103d84a3 922 pr_debug("ASoC: %s <-> %s info:\n",
19bdcc7a 923 codec_dai_name, cpu_dai_name);
103d84a3
LG
924 pr_debug("ASoC: rate mask 0x%x\n", runtime->hw.rates);
925 pr_debug("ASoC: min ch %d max ch %d\n", runtime->hw.channels_min,
ddee627c 926 runtime->hw.channels_max);
103d84a3 927 pr_debug("ASoC: min rate %d max rate %d\n", runtime->hw.rate_min,
ddee627c
LG
928 runtime->hw.rate_max);
929
01d7584c 930dynamic:
24894b76
LPC
931
932 snd_soc_runtime_activate(rtd, substream->stream);
933
72b745e3 934 mutex_unlock(&rtd->card->pcm_mutex);
ddee627c
LG
935 return 0;
936
937config_err:
a4be4187 938 for_each_rtd_codec_dais(rtd, i, codec_dai)
330fcb51 939 snd_soc_dai_shutdown(codec_dai, substream);
5d9fa03e 940cpu_dai_err:
a4be4187 941 for_each_rtd_cpu_dais(rtd, i, cpu_dai)
19bdcc7a 942 snd_soc_dai_shutdown(cpu_dai, substream);
2e5894d7 943
5d9fa03e 944 soc_rtd_shutdown(rtd, substream);
d2aaa8d8 945rtd_startup_err:
dd03907b 946 soc_pcm_components_close(substream);
d2aaa8d8 947component_err:
72b745e3 948 mutex_unlock(&rtd->card->pcm_mutex);
d6652ef8 949
613fb500 950 for_each_rtd_components(rtd, i, component) {
90be711e
KM
951 pm_runtime_mark_last_busy(component->dev);
952 pm_runtime_put_autosuspend(component->dev);
3f809783
SK
953 }
954
76c39e86
KM
955 for_each_rtd_components(rtd, i, component)
956 if (!component->active)
957 pinctrl_pm_select_sleep_state(component->dev);
d6652ef8 958
ddee627c
LG
959 return ret;
960}
961
4bf2e385 962static void codec2codec_close_delayed_work(struct snd_soc_pcm_runtime *rtd)
a342031c
JB
963{
964 /*
965 * Currently nothing to do for c2c links
966 * Since c2c links are internal nodes in the DAPM graph and
967 * don't interface with the outside world or application layer
968 * we don't have to do any special handling on close.
969 */
970}
971
ddee627c
LG
972/*
973 * Called by ALSA when the PCM substream is prepared, can set format, sample
974 * rate, etc. This function is non atomic and can be called multiple times,
975 * it can refer to the runtime info.
976 */
977static int soc_pcm_prepare(struct snd_pcm_substream *substream)
978{
979 struct snd_soc_pcm_runtime *rtd = substream->private_data;
b8135864 980 struct snd_soc_component *component;
19bdcc7a 981 struct snd_soc_dai *cpu_dai;
2e5894d7
BC
982 struct snd_soc_dai *codec_dai;
983 int i, ret = 0;
ddee627c 984
72b745e3 985 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
ddee627c 986
44c1a75b
KM
987 ret = soc_rtd_prepare(rtd, substream);
988 if (ret < 0) {
989 dev_err(rtd->card->dev,
990 "ASoC: machine prepare error: %d\n", ret);
991 goto out;
ddee627c
LG
992 }
993
613fb500 994 for_each_rtd_components(rtd, i, component) {
6d537233 995 ret = snd_soc_component_prepare(component, substream);
b8135864
KM
996 if (ret < 0) {
997 dev_err(component->dev,
998 "ASoC: platform prepare error: %d\n", ret);
999 goto out;
1000 }
1001 }
1002
a4be4187 1003 for_each_rtd_codec_dais(rtd, i, codec_dai) {
4beb8e10 1004 ret = snd_soc_dai_prepare(codec_dai, substream);
ddee627c 1005 if (ret < 0) {
4beb8e10
KM
1006 dev_err(codec_dai->dev,
1007 "ASoC: codec DAI prepare error: %d\n",
1008 ret);
ddee627c
LG
1009 goto out;
1010 }
1011 }
1012
a4be4187 1013 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
1014 ret = snd_soc_dai_prepare(cpu_dai, substream);
1015 if (ret < 0) {
1016 dev_err(cpu_dai->dev,
1017 "ASoC: cpu DAI prepare error: %d\n", ret);
1018 goto out;
1019 }
4beb8e10
KM
1020 }
1021
ddee627c
LG
1022 /* cancel any delayed stream shutdown that is pending */
1023 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
9bffb1fb
MLC
1024 rtd->pop_wait) {
1025 rtd->pop_wait = 0;
ddee627c
LG
1026 cancel_delayed_work(&rtd->delayed_work);
1027 }
1028
d9b0951b
LG
1029 snd_soc_dapm_stream_event(rtd, substream->stream,
1030 SND_SOC_DAPM_STREAM_START);
ddee627c 1031
a4be4187 1032 for_each_rtd_codec_dais(rtd, i, codec_dai)
0b7990e3 1033 snd_soc_dai_digital_mute(codec_dai, 0,
2e5894d7 1034 substream->stream);
a4be4187 1035 for_each_rtd_cpu_dais(rtd, i, cpu_dai)
19bdcc7a 1036 snd_soc_dai_digital_mute(cpu_dai, 0, substream->stream);
ddee627c
LG
1037
1038out:
72b745e3 1039 mutex_unlock(&rtd->card->pcm_mutex);
ddee627c
LG
1040 return ret;
1041}
1042
2e5894d7
BC
1043static void soc_pcm_codec_params_fixup(struct snd_pcm_hw_params *params,
1044 unsigned int mask)
1045{
1046 struct snd_interval *interval;
1047 int channels = hweight_long(mask);
1048
1049 interval = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
1050 interval->min = channels;
1051 interval->max = channels;
1052}
1053
244e2936
CK
1054static int soc_pcm_components_hw_free(struct snd_pcm_substream *substream,
1055 struct snd_soc_component *last)
1056{
1057 struct snd_soc_pcm_runtime *rtd = substream->private_data;
244e2936 1058 struct snd_soc_component *component;
e82ebffc 1059 int i, r, ret = 0;
244e2936 1060
613fb500 1061 for_each_rtd_components(rtd, i, component) {
244e2936
CK
1062 if (component == last)
1063 break;
1064
e82ebffc
KM
1065 r = snd_soc_component_hw_free(component, substream);
1066 if (r < 0)
1067 ret = r; /* use last ret */
244e2936
CK
1068 }
1069
eae7136a 1070 return ret;
244e2936
CK
1071}
1072
ddee627c
LG
1073/*
1074 * Called by ALSA when the hardware params are set by application. This
1075 * function can also be called multiple times and can allocate buffers
1076 * (using snd_pcm_lib_* ). It's non-atomic.
1077 */
1078static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
1079 struct snd_pcm_hw_params *params)
1080{
1081 struct snd_soc_pcm_runtime *rtd = substream->private_data;
b8135864 1082 struct snd_soc_component *component;
19bdcc7a 1083 struct snd_soc_dai *cpu_dai;
0b7990e3 1084 struct snd_soc_dai *codec_dai;
244e2936 1085 int i, ret = 0;
ddee627c 1086
72b745e3 1087 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
5cca5951
SW
1088
1089 ret = soc_pcm_params_symmetry(substream, params);
1090 if (ret)
1091 goto out;
1092
de9ad990
KM
1093 ret = soc_rtd_hw_params(rtd, substream, params);
1094 if (ret < 0) {
1095 dev_err(rtd->card->dev,
1096 "ASoC: machine hw_params failed: %d\n", ret);
1097 goto out;
ddee627c
LG
1098 }
1099
a4be4187 1100 for_each_rtd_codec_dais(rtd, i, codec_dai) {
2e5894d7
BC
1101 struct snd_pcm_hw_params codec_params;
1102
cde79035
RW
1103 /*
1104 * Skip CODECs which don't support the current stream type,
1105 * the idea being that if a CODEC is not used for the currently
1106 * set up transfer direction, it should not need to be
1107 * configured, especially since the configuration used might
1108 * not even be supported by that CODEC. There may be cases
1109 * however where a CODEC needs to be set up although it is
1110 * actually not being used for the transfer, e.g. if a
1111 * capture-only CODEC is acting as an LRCLK and/or BCLK master
1112 * for the DAI link including a playback-only CODEC.
1113 * If this becomes necessary, we will have to augment the
1114 * machine driver setup with information on how to act, so
1115 * we can do the right thing here.
1116 */
1117 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
1118 continue;
1119
2e5894d7
BC
1120 /* copy params for each codec */
1121 codec_params = *params;
1122
1123 /* fixup params based on TDM slot masks */
570f18b6
RW
1124 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
1125 codec_dai->tx_mask)
2e5894d7
BC
1126 soc_pcm_codec_params_fixup(&codec_params,
1127 codec_dai->tx_mask);
570f18b6
RW
1128
1129 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
1130 codec_dai->rx_mask)
2e5894d7
BC
1131 soc_pcm_codec_params_fixup(&codec_params,
1132 codec_dai->rx_mask);
1133
aa6166c2
KM
1134 ret = snd_soc_dai_hw_params(codec_dai, substream,
1135 &codec_params);
93e6958a 1136 if(ret < 0)
ddee627c 1137 goto codec_err;
ddee627c 1138
2e5894d7
BC
1139 codec_dai->rate = params_rate(&codec_params);
1140 codec_dai->channels = params_channels(&codec_params);
1141 codec_dai->sample_bits = snd_pcm_format_physical_width(
1142 params_format(&codec_params));
078a85f2
CK
1143
1144 snd_soc_dapm_update_dai(substream, &codec_params, codec_dai);
ddee627c
LG
1145 }
1146
a4be4187 1147 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
0e9cf4c4
BL
1148 /*
1149 * Skip CPUs which don't support the current stream
1150 * type. See soc_pcm_init_runtime_hw() for more details
1151 */
1152 if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream))
1153 continue;
1154
19bdcc7a
SN
1155 ret = snd_soc_dai_hw_params(cpu_dai, substream, params);
1156 if (ret < 0)
1157 goto interface_err;
ddee627c 1158
19bdcc7a
SN
1159 /* store the parameters for each DAI */
1160 cpu_dai->rate = params_rate(params);
1161 cpu_dai->channels = params_channels(params);
1162 cpu_dai->sample_bits =
1163 snd_pcm_format_physical_width(params_format(params));
ca58221d 1164
19bdcc7a
SN
1165 snd_soc_dapm_update_dai(substream, params, cpu_dai);
1166 }
ca58221d 1167
613fb500 1168 for_each_rtd_components(rtd, i, component) {
245c539a 1169 ret = snd_soc_component_hw_params(component, substream, params);
244e2936 1170 if (ret < 0) {
b8135864
KM
1171 dev_err(component->dev,
1172 "ASoC: %s hw params failed: %d\n",
244e2936
CK
1173 component->name, ret);
1174 goto component_err;
b8135864
KM
1175 }
1176 }
244e2936 1177 component = NULL;
b8135864 1178
ddee627c 1179out:
72b745e3 1180 mutex_unlock(&rtd->card->pcm_mutex);
ddee627c
LG
1181 return ret;
1182
b8135864 1183component_err:
244e2936 1184 soc_pcm_components_hw_free(substream, component);
b8135864 1185
19bdcc7a 1186 i = rtd->num_cpus;
ddee627c
LG
1187
1188interface_err:
a4be4187 1189 for_each_rtd_cpu_dais_rollback(rtd, i, cpu_dai) {
0e9cf4c4
BL
1190 if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream))
1191 continue;
1192
19bdcc7a
SN
1193 snd_soc_dai_hw_free(cpu_dai, substream);
1194 cpu_dai->rate = 0;
1195 }
1196
2e5894d7 1197 i = rtd->num_codecs;
ddee627c
LG
1198
1199codec_err:
a4be4187 1200 for_each_rtd_codec_dais_rollback(rtd, i, codec_dai) {
f47b9ad9
JB
1201 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
1202 continue;
1203
846faaed 1204 snd_soc_dai_hw_free(codec_dai, substream);
2e5894d7
BC
1205 codec_dai->rate = 0;
1206 }
1207
49f020e5 1208 soc_rtd_hw_free(rtd, substream);
ddee627c 1209
72b745e3 1210 mutex_unlock(&rtd->card->pcm_mutex);
ddee627c
LG
1211 return ret;
1212}
1213
1214/*
1215 * Frees resources allocated by hw_params, can be called multiple times
1216 */
1217static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
1218{
1219 struct snd_soc_pcm_runtime *rtd = substream->private_data;
19bdcc7a 1220 struct snd_soc_dai *cpu_dai;
2e5894d7 1221 struct snd_soc_dai *codec_dai;
2e5894d7 1222 int i;
ddee627c 1223
72b745e3 1224 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
ddee627c 1225
d3383420 1226 /* clear the corresponding DAIs parameters when going to be inactive */
a4be4187 1227 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
1228 if (cpu_dai->active == 1) {
1229 cpu_dai->rate = 0;
1230 cpu_dai->channels = 0;
1231 cpu_dai->sample_bits = 0;
1232 }
d3383420
NC
1233 }
1234
a4be4187 1235 for_each_rtd_codec_dais(rtd, i, codec_dai) {
2e5894d7
BC
1236 if (codec_dai->active == 1) {
1237 codec_dai->rate = 0;
1238 codec_dai->channels = 0;
1239 codec_dai->sample_bits = 0;
1240 }
d3383420
NC
1241 }
1242
ddee627c 1243 /* apply codec digital mute */
a4be4187 1244 for_each_rtd_codec_dais(rtd, i, codec_dai) {
67ad8777 1245 int active = codec_dai->stream_active[substream->stream];
0f6011fd 1246
67ad8777 1247 if (active == 1)
0b7990e3 1248 snd_soc_dai_digital_mute(codec_dai, 1,
2e5894d7
BC
1249 substream->stream);
1250 }
ddee627c 1251
a4be4187 1252 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
a9ee331b
KM
1253 int active = cpu_dai->stream_active[substream->stream];
1254
1255 if (active == 1)
1256 snd_soc_dai_digital_mute(cpu_dai, 1,
1257 substream->stream);
1258 }
1259
ddee627c 1260 /* free any machine hw params */
49f020e5 1261 soc_rtd_hw_free(rtd, substream);
ddee627c 1262
b8135864 1263 /* free any component resources */
244e2936 1264 soc_pcm_components_hw_free(substream, NULL);
b8135864 1265
ddee627c 1266 /* now free hw params for the DAIs */
a4be4187 1267 for_each_rtd_codec_dais(rtd, i, codec_dai) {
f47b9ad9
JB
1268 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
1269 continue;
1270
846faaed 1271 snd_soc_dai_hw_free(codec_dai, substream);
2e5894d7 1272 }
ddee627c 1273
a4be4187 1274 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
0e9cf4c4
BL
1275 if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream))
1276 continue;
1277
19bdcc7a 1278 snd_soc_dai_hw_free(cpu_dai, substream);
0e9cf4c4 1279 }
ddee627c 1280
72b745e3 1281 mutex_unlock(&rtd->card->pcm_mutex);
ddee627c
LG
1282 return 0;
1283}
1284
4378f1fb 1285static int soc_pcm_trigger_start(struct snd_pcm_substream *substream, int cmd)
ddee627c
LG
1286{
1287 struct snd_soc_pcm_runtime *rtd = substream->private_data;
b8135864 1288 struct snd_soc_component *component;
19bdcc7a 1289 struct snd_soc_dai *cpu_dai;
2e5894d7
BC
1290 struct snd_soc_dai *codec_dai;
1291 int i, ret;
1292
ad2bf9f2
KM
1293 ret = soc_rtd_trigger(rtd, substream, cmd);
1294 if (ret < 0)
1295 return ret;
ddee627c 1296
613fb500 1297 for_each_rtd_components(rtd, i, component) {
5693d50c 1298 ret = snd_soc_component_trigger(component, substream, cmd);
b8135864
KM
1299 if (ret < 0)
1300 return ret;
1301 }
1302
a4be4187 1303 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
1304 ret = snd_soc_dai_trigger(cpu_dai, substream, cmd);
1305 if (ret < 0)
1306 return ret;
1307 }
4792b0db 1308
a4be4187 1309 for_each_rtd_codec_dais(rtd, i, codec_dai) {
4378f1fb
PU
1310 ret = snd_soc_dai_trigger(codec_dai, substream, cmd);
1311 if (ret < 0)
1312 return ret;
1313 }
1314
1315 return 0;
1316}
1317
1318static int soc_pcm_trigger_stop(struct snd_pcm_substream *substream, int cmd)
1319{
1320 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1321 struct snd_soc_component *component;
19bdcc7a 1322 struct snd_soc_dai *cpu_dai;
4378f1fb
PU
1323 struct snd_soc_dai *codec_dai;
1324 int i, ret;
1325
a4be4187 1326 for_each_rtd_codec_dais(rtd, i, codec_dai) {
4378f1fb
PU
1327 ret = snd_soc_dai_trigger(codec_dai, substream, cmd);
1328 if (ret < 0)
1329 return ret;
1330 }
1331
a4be4187 1332 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
1333 ret = snd_soc_dai_trigger(cpu_dai, substream, cmd);
1334 if (ret < 0)
1335 return ret;
1336 }
4378f1fb 1337
613fb500 1338 for_each_rtd_components(rtd, i, component) {
4378f1fb
PU
1339 ret = snd_soc_component_trigger(component, substream, cmd);
1340 if (ret < 0)
1341 return ret;
1342 }
1343
ad2bf9f2
KM
1344 ret = soc_rtd_trigger(rtd, substream, cmd);
1345 if (ret < 0)
1346 return ret;
4792b0db 1347
ddee627c
LG
1348 return 0;
1349}
1350
4378f1fb
PU
1351static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1352{
1353 int ret;
1354
1355 switch (cmd) {
1356 case SNDRV_PCM_TRIGGER_START:
1357 case SNDRV_PCM_TRIGGER_RESUME:
1358 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1359 ret = soc_pcm_trigger_start(substream, cmd);
1360 break;
1361 case SNDRV_PCM_TRIGGER_STOP:
1362 case SNDRV_PCM_TRIGGER_SUSPEND:
1363 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1364 ret = soc_pcm_trigger_stop(substream, cmd);
1365 break;
1366 default:
1367 return -EINVAL;
1368 }
1369
1370 return ret;
1371}
1372
45c0a188
MB
1373static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
1374 int cmd)
07bf84aa
LG
1375{
1376 struct snd_soc_pcm_runtime *rtd = substream->private_data;
19bdcc7a 1377 struct snd_soc_dai *cpu_dai;
2e5894d7
BC
1378 struct snd_soc_dai *codec_dai;
1379 int i, ret;
1380
a4be4187 1381 for_each_rtd_codec_dais(rtd, i, codec_dai) {
5c0769af 1382 ret = snd_soc_dai_bespoke_trigger(codec_dai, substream, cmd);
07bf84aa
LG
1383 if (ret < 0)
1384 return ret;
1385 }
5c0769af 1386
a4be4187 1387 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
1388 ret = snd_soc_dai_bespoke_trigger(cpu_dai, substream, cmd);
1389 if (ret < 0)
1390 return ret;
1391 }
5c0769af 1392
07bf84aa
LG
1393 return 0;
1394}
ddee627c
LG
1395/*
1396 * soc level wrapper for pointer callback
ef050bec 1397 * If cpu_dai, codec_dai, component driver has the delay callback, then
ddee627c
LG
1398 * the runtime->delay will be updated accordingly.
1399 */
1400static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
1401{
1402 struct snd_soc_pcm_runtime *rtd = substream->private_data;
19bdcc7a 1403 struct snd_soc_dai *cpu_dai;
2e5894d7 1404 struct snd_soc_dai *codec_dai;
ddee627c
LG
1405 struct snd_pcm_runtime *runtime = substream->runtime;
1406 snd_pcm_uframes_t offset = 0;
1407 snd_pcm_sframes_t delay = 0;
2e5894d7 1408 snd_pcm_sframes_t codec_delay = 0;
19bdcc7a 1409 snd_pcm_sframes_t cpu_delay = 0;
2e5894d7 1410 int i;
ddee627c 1411
9fb4c2bf
AA
1412 /* clearing the previous total delay */
1413 runtime->delay = 0;
1414
0035e256 1415 offset = snd_soc_pcm_component_pointer(substream);
b8135864 1416
9fb4c2bf
AA
1417 /* base delay if assigned in pointer callback */
1418 delay = runtime->delay;
b8135864 1419
a4be4187 1420 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
1421 cpu_delay = max(cpu_delay,
1422 snd_soc_dai_delay(cpu_dai, substream));
1423 }
1424 delay += cpu_delay;
ddee627c 1425
a4be4187 1426 for_each_rtd_codec_dais(rtd, i, codec_dai) {
1dea80d4
KM
1427 codec_delay = max(codec_delay,
1428 snd_soc_dai_delay(codec_dai, substream));
2e5894d7
BC
1429 }
1430 delay += codec_delay;
ddee627c 1431
ddee627c
LG
1432 runtime->delay = delay;
1433
1434 return offset;
1435}
1436
01d7584c
LG
1437/* connect a FE and BE */
1438static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
1439 struct snd_soc_pcm_runtime *be, int stream)
1440{
1441 struct snd_soc_dpcm *dpcm;
a9764869 1442 unsigned long flags;
01d7584c
LG
1443
1444 /* only add new dpcms */
8d6258a4 1445 for_each_dpcm_be(fe, stream, dpcm) {
01d7584c
LG
1446 if (dpcm->be == be && dpcm->fe == fe)
1447 return 0;
1448 }
1449
1450 dpcm = kzalloc(sizeof(struct snd_soc_dpcm), GFP_KERNEL);
1451 if (!dpcm)
1452 return -ENOMEM;
1453
1454 dpcm->be = be;
1455 dpcm->fe = fe;
1456 be->dpcm[stream].runtime = fe->dpcm[stream].runtime;
1457 dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW;
a9764869 1458 spin_lock_irqsave(&fe->card->dpcm_lock, flags);
01d7584c
LG
1459 list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients);
1460 list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients);
a9764869 1461 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
01d7584c 1462
7cc302d2 1463 dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n",
01d7584c
LG
1464 stream ? "capture" : "playback", fe->dai_link->name,
1465 stream ? "<-" : "->", be->dai_link->name);
1466
154dae87
KM
1467 dpcm_create_debugfs_state(dpcm, stream);
1468
01d7584c
LG
1469 return 1;
1470}
1471
1472/* reparent a BE onto another FE */
1473static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
1474 struct snd_soc_pcm_runtime *be, int stream)
1475{
1476 struct snd_soc_dpcm *dpcm;
1477 struct snd_pcm_substream *fe_substream, *be_substream;
1478
1479 /* reparent if BE is connected to other FEs */
1480 if (!be->dpcm[stream].users)
1481 return;
1482
1483 be_substream = snd_soc_dpcm_get_substream(be, stream);
1484
d2e24d64 1485 for_each_dpcm_fe(be, stream, dpcm) {
01d7584c
LG
1486 if (dpcm->fe == fe)
1487 continue;
1488
7cc302d2 1489 dev_dbg(fe->dev, "reparent %s path %s %s %s\n",
01d7584c
LG
1490 stream ? "capture" : "playback",
1491 dpcm->fe->dai_link->name,
1492 stream ? "<-" : "->", dpcm->be->dai_link->name);
1493
1494 fe_substream = snd_soc_dpcm_get_substream(dpcm->fe, stream);
1495 be_substream->runtime = fe_substream->runtime;
1496 break;
1497 }
1498}
1499
1500/* disconnect a BE and FE */
23607025 1501void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
01d7584c
LG
1502{
1503 struct snd_soc_dpcm *dpcm, *d;
a9764869 1504 unsigned long flags;
01d7584c 1505
8d6258a4 1506 for_each_dpcm_be_safe(fe, stream, dpcm, d) {
103d84a3 1507 dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n",
01d7584c
LG
1508 stream ? "capture" : "playback",
1509 dpcm->be->dai_link->name);
1510
1511 if (dpcm->state != SND_SOC_DPCM_LINK_STATE_FREE)
1512 continue;
1513
7cc302d2 1514 dev_dbg(fe->dev, "freed DSP %s path %s %s %s\n",
01d7584c
LG
1515 stream ? "capture" : "playback", fe->dai_link->name,
1516 stream ? "<-" : "->", dpcm->be->dai_link->name);
1517
1518 /* BEs still alive need new FE */
1519 dpcm_be_reparent(fe, dpcm->be, stream);
1520
154dae87
KM
1521 dpcm_remove_debugfs_state(dpcm);
1522
a9764869 1523 spin_lock_irqsave(&fe->card->dpcm_lock, flags);
01d7584c
LG
1524 list_del(&dpcm->list_be);
1525 list_del(&dpcm->list_fe);
a9764869 1526 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
01d7584c
LG
1527 kfree(dpcm);
1528 }
1529}
1530
1531/* get BE for DAI widget and stream */
1532static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
1533 struct snd_soc_dapm_widget *widget, int stream)
1534{
1535 struct snd_soc_pcm_runtime *be;
93597fae 1536 struct snd_soc_dapm_widget *w;
7afecb30 1537 struct snd_soc_dai *dai;
1a497983 1538 int i;
01d7584c 1539
3c146465
LG
1540 dev_dbg(card->dev, "ASoC: find BE for widget %s\n", widget->name);
1541
93597fae 1542 for_each_card_rtds(card, be) {
01d7584c 1543
93597fae
KM
1544 if (!be->dai_link->no_pcm)
1545 continue;
35ea0655 1546
a4be4187 1547 for_each_rtd_cpu_dais(be, i, dai) {
19bdcc7a 1548 w = snd_soc_dai_get_widget(dai, stream);
3c146465 1549
19bdcc7a
SN
1550 dev_dbg(card->dev, "ASoC: try BE : %s\n",
1551 w ? w->name : "(not set)");
2e5894d7 1552
19bdcc7a
SN
1553 if (w == widget)
1554 return be;
1555 }
35ea0655 1556
a4be4187 1557 for_each_rtd_codec_dais(be, i, dai) {
0c01f6ca 1558 w = snd_soc_dai_get_widget(dai, stream);
3c146465 1559
93597fae 1560 if (w == widget)
01d7584c
LG
1561 return be;
1562 }
1563 }
1564
9d6ee365 1565 /* Widget provided is not a BE */
01d7584c
LG
1566 return NULL;
1567}
1568
01d7584c
LG
1569static int widget_in_list(struct snd_soc_dapm_widget_list *list,
1570 struct snd_soc_dapm_widget *widget)
1571{
09e88f8a 1572 struct snd_soc_dapm_widget *w;
01d7584c
LG
1573 int i;
1574
09e88f8a
KM
1575 for_each_dapm_widgets(list, i, w)
1576 if (widget == w)
01d7584c 1577 return 1;
01d7584c
LG
1578
1579 return 0;
1580}
1581
5fdd022c
PS
1582static bool dpcm_end_walk_at_be(struct snd_soc_dapm_widget *widget,
1583 enum snd_soc_dapm_direction dir)
1584{
1585 struct snd_soc_card *card = widget->dapm->card;
1586 struct snd_soc_pcm_runtime *rtd;
c2cd8216 1587 int stream;
5fdd022c 1588
c2cd8216
KM
1589 /* adjust dir to stream */
1590 if (dir == SND_SOC_DAPM_DIR_OUT)
1591 stream = SNDRV_PCM_STREAM_PLAYBACK;
1592 else
1593 stream = SNDRV_PCM_STREAM_CAPTURE;
5fdd022c 1594
027a4838
KM
1595 rtd = dpcm_get_be(card, widget, stream);
1596 if (rtd)
1597 return true;
5fdd022c
PS
1598
1599 return false;
1600}
1601
23607025 1602int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
1ce43acf 1603 int stream, struct snd_soc_dapm_widget_list **list)
01d7584c
LG
1604{
1605 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
01d7584c
LG
1606 int paths;
1607
6e1276a5
BL
1608 if (fe->num_cpus > 1) {
1609 dev_err(fe->dev,
1610 "%s doesn't support Multi CPU yet\n", __func__);
1611 return -EINVAL;
1612 }
1613
01d7584c 1614 /* get number of valid DAI paths and their widgets */
6742064a 1615 paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, list,
5fdd022c 1616 dpcm_end_walk_at_be);
01d7584c 1617
103d84a3 1618 dev_dbg(fe->dev, "ASoC: found %d audio %s paths\n", paths,
01d7584c
LG
1619 stream ? "capture" : "playback");
1620
01d7584c
LG
1621 return paths;
1622}
1623
52645e33
KM
1624void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
1625{
1626 snd_soc_dapm_dai_free_widgets(list);
1627}
1628
01d7584c
LG
1629static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
1630 struct snd_soc_dapm_widget_list **list_)
1631{
1632 struct snd_soc_dpcm *dpcm;
1633 struct snd_soc_dapm_widget_list *list = *list_;
1634 struct snd_soc_dapm_widget *widget;
7afecb30 1635 struct snd_soc_dai *dai;
01d7584c 1636 int prune = 0;
bed646dc 1637 int do_prune;
01d7584c
LG
1638
1639 /* Destroy any old FE <--> BE connections */
8d6258a4 1640 for_each_dpcm_be(fe, stream, dpcm) {
2e5894d7 1641 unsigned int i;
01d7584c
LG
1642
1643 /* is there a valid CPU DAI widget for this BE */
19bdcc7a 1644 do_prune = 1;
a4be4187 1645 for_each_rtd_cpu_dais(dpcm->be, i, dai) {
19bdcc7a 1646 widget = snd_soc_dai_get_widget(dai, stream);
01d7584c 1647
19bdcc7a
SN
1648 /*
1649 * The BE is pruned only if none of the cpu_dai
1650 * widgets are in the active list.
1651 */
1652 if (widget && widget_in_list(list, widget))
1653 do_prune = 0;
1654 }
1655 if (!do_prune)
01d7584c
LG
1656 continue;
1657
1658 /* is there a valid CODEC DAI widget for this BE */
bed646dc 1659 do_prune = 1;
a4be4187 1660 for_each_rtd_codec_dais(dpcm->be, i, dai) {
0c01f6ca 1661 widget = snd_soc_dai_get_widget(dai, stream);
01d7584c 1662
2e5894d7
BC
1663 /* prune the BE if it's no longer in our active list */
1664 if (widget && widget_in_list(list, widget))
bed646dc 1665 do_prune = 0;
2e5894d7 1666 }
bed646dc
KM
1667 if (!do_prune)
1668 continue;
01d7584c 1669
103d84a3 1670 dev_dbg(fe->dev, "ASoC: pruning %s BE %s for %s\n",
01d7584c
LG
1671 stream ? "capture" : "playback",
1672 dpcm->be->dai_link->name, fe->dai_link->name);
1673 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
1674 dpcm->be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
1675 prune++;
1676 }
1677
103d84a3 1678 dev_dbg(fe->dev, "ASoC: found %d old BE paths for pruning\n", prune);
01d7584c
LG
1679 return prune;
1680}
1681
1682static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
1683 struct snd_soc_dapm_widget_list **list_)
1684{
1685 struct snd_soc_card *card = fe->card;
1686 struct snd_soc_dapm_widget_list *list = *list_;
1687 struct snd_soc_pcm_runtime *be;
09e88f8a 1688 struct snd_soc_dapm_widget *widget;
01d7584c
LG
1689 int i, new = 0, err;
1690
1691 /* Create any new FE <--> BE connections */
09e88f8a 1692 for_each_dapm_widgets(list, i, widget) {
01d7584c 1693
09e88f8a 1694 switch (widget->id) {
4616274d 1695 case snd_soc_dapm_dai_in:
c5b8540d
KC
1696 if (stream != SNDRV_PCM_STREAM_PLAYBACK)
1697 continue;
1698 break;
4616274d 1699 case snd_soc_dapm_dai_out:
c5b8540d
KC
1700 if (stream != SNDRV_PCM_STREAM_CAPTURE)
1701 continue;
4616274d
MB
1702 break;
1703 default:
01d7584c 1704 continue;
4616274d 1705 }
01d7584c
LG
1706
1707 /* is there a valid BE rtd for this widget */
09e88f8a 1708 be = dpcm_get_be(card, widget, stream);
01d7584c 1709 if (!be) {
103d84a3 1710 dev_err(fe->dev, "ASoC: no BE found for %s\n",
09e88f8a 1711 widget->name);
01d7584c
LG
1712 continue;
1713 }
1714
01d7584c 1715 /* don't connect if FE is not running */
23607025 1716 if (!fe->dpcm[stream].runtime && !fe->fe_compr)
01d7584c
LG
1717 continue;
1718
1719 /* newly connected FE and BE */
1720 err = dpcm_be_connect(fe, be, stream);
1721 if (err < 0) {
103d84a3 1722 dev_err(fe->dev, "ASoC: can't connect %s\n",
09e88f8a 1723 widget->name);
01d7584c
LG
1724 break;
1725 } else if (err == 0) /* already connected */
1726 continue;
1727
1728 /* new */
1729 be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
1730 new++;
1731 }
1732
103d84a3 1733 dev_dbg(fe->dev, "ASoC: found %d new BE paths\n", new);
01d7584c
LG
1734 return new;
1735}
1736
1737/*
1738 * Find the corresponding BE DAIs that source or sink audio to this
1739 * FE substream.
1740 */
23607025 1741int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
01d7584c
LG
1742 int stream, struct snd_soc_dapm_widget_list **list, int new)
1743{
1744 if (new)
1745 return dpcm_add_paths(fe, stream, list);
1746 else
1747 return dpcm_prune_paths(fe, stream, list);
1748}
1749
23607025 1750void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream)
01d7584c
LG
1751{
1752 struct snd_soc_dpcm *dpcm;
a9764869 1753 unsigned long flags;
01d7584c 1754
a9764869 1755 spin_lock_irqsave(&fe->card->dpcm_lock, flags);
8d6258a4 1756 for_each_dpcm_be(fe, stream, dpcm)
01d7584c
LG
1757 dpcm->be->dpcm[stream].runtime_update =
1758 SND_SOC_DPCM_UPDATE_NO;
a9764869 1759 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
01d7584c
LG
1760}
1761
1762static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe,
1763 int stream)
1764{
1765 struct snd_soc_dpcm *dpcm;
1766
1767 /* disable any enabled and non active backends */
8d6258a4 1768 for_each_dpcm_be(fe, stream, dpcm) {
01d7584c
LG
1769
1770 struct snd_soc_pcm_runtime *be = dpcm->be;
1771 struct snd_pcm_substream *be_substream =
1772 snd_soc_dpcm_get_substream(be, stream);
1773
1774 if (be->dpcm[stream].users == 0)
103d84a3 1775 dev_err(be->dev, "ASoC: no users %s at close - state %d\n",
01d7584c
LG
1776 stream ? "capture" : "playback",
1777 be->dpcm[stream].state);
1778
1779 if (--be->dpcm[stream].users != 0)
1780 continue;
1781
1782 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)
1783 continue;
1784
1785 soc_pcm_close(be_substream);
1786 be_substream->runtime = NULL;
1787 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1788 }
1789}
1790
23607025 1791int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
01d7584c
LG
1792{
1793 struct snd_soc_dpcm *dpcm;
1794 int err, count = 0;
1795
1796 /* only startup BE DAIs that are either sinks or sources to this FE DAI */
8d6258a4 1797 for_each_dpcm_be(fe, stream, dpcm) {
01d7584c
LG
1798
1799 struct snd_soc_pcm_runtime *be = dpcm->be;
1800 struct snd_pcm_substream *be_substream =
1801 snd_soc_dpcm_get_substream(be, stream);
1802
2062b4c5
RKAL
1803 if (!be_substream) {
1804 dev_err(be->dev, "ASoC: no backend %s stream\n",
1805 stream ? "capture" : "playback");
1806 continue;
1807 }
1808
01d7584c
LG
1809 /* is this op for this BE ? */
1810 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1811 continue;
1812
1813 /* first time the dpcm is open ? */
1814 if (be->dpcm[stream].users == DPCM_MAX_BE_USERS)
103d84a3 1815 dev_err(be->dev, "ASoC: too many users %s at open %d\n",
01d7584c
LG
1816 stream ? "capture" : "playback",
1817 be->dpcm[stream].state);
1818
1819 if (be->dpcm[stream].users++ != 0)
1820 continue;
1821
1822 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_NEW) &&
1823 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE))
1824 continue;
1825
2062b4c5
RKAL
1826 dev_dbg(be->dev, "ASoC: open %s BE %s\n",
1827 stream ? "capture" : "playback", be->dai_link->name);
01d7584c
LG
1828
1829 be_substream->runtime = be->dpcm[stream].runtime;
1830 err = soc_pcm_open(be_substream);
1831 if (err < 0) {
103d84a3 1832 dev_err(be->dev, "ASoC: BE open failed %d\n", err);
01d7584c
LG
1833 be->dpcm[stream].users--;
1834 if (be->dpcm[stream].users < 0)
103d84a3 1835 dev_err(be->dev, "ASoC: no users %s at unwind %d\n",
01d7584c
LG
1836 stream ? "capture" : "playback",
1837 be->dpcm[stream].state);
1838
1839 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1840 goto unwind;
1841 }
1842
1843 be->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
1844 count++;
1845 }
1846
1847 return count;
1848
1849unwind:
1850 /* disable any enabled and non active backends */
8d6258a4 1851 for_each_dpcm_be_rollback(fe, stream, dpcm) {
01d7584c
LG
1852 struct snd_soc_pcm_runtime *be = dpcm->be;
1853 struct snd_pcm_substream *be_substream =
1854 snd_soc_dpcm_get_substream(be, stream);
1855
1856 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1857 continue;
1858
1859 if (be->dpcm[stream].users == 0)
103d84a3 1860 dev_err(be->dev, "ASoC: no users %s at close %d\n",
01d7584c
LG
1861 stream ? "capture" : "playback",
1862 be->dpcm[stream].state);
1863
1864 if (--be->dpcm[stream].users != 0)
1865 continue;
1866
1867 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)
1868 continue;
1869
1870 soc_pcm_close(be_substream);
1871 be_substream->runtime = NULL;
1872 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1873 }
1874
1875 return err;
1876}
1877
08ae9b45 1878static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime,
435ffb76 1879 struct snd_soc_pcm_stream *stream)
08ae9b45
LPC
1880{
1881 runtime->hw.rate_min = stream->rate_min;
e33ffbd9 1882 runtime->hw.rate_max = min_not_zero(stream->rate_max, UINT_MAX);
08ae9b45
LPC
1883 runtime->hw.channels_min = stream->channels_min;
1884 runtime->hw.channels_max = stream->channels_max;
002220a9 1885 if (runtime->hw.formats)
435ffb76 1886 runtime->hw.formats &= stream->formats;
002220a9 1887 else
435ffb76 1888 runtime->hw.formats = stream->formats;
08ae9b45
LPC
1889 runtime->hw.rates = stream->rates;
1890}
1891
435ffb76
JB
1892static void dpcm_runtime_merge_format(struct snd_pcm_substream *substream,
1893 u64 *formats)
b073ed4e
KM
1894{
1895 struct snd_soc_pcm_runtime *fe = substream->private_data;
1896 struct snd_soc_dpcm *dpcm;
7afecb30 1897 struct snd_soc_dai *dai;
b073ed4e
KM
1898 int stream = substream->stream;
1899
1900 if (!fe->dai_link->dpcm_merged_format)
435ffb76 1901 return;
b073ed4e
KM
1902
1903 /*
1904 * It returns merged BE codec format
1905 * if FE want to use it (= dpcm_merged_format)
1906 */
1907
8d6258a4 1908 for_each_dpcm_be(fe, stream, dpcm) {
b073ed4e 1909 struct snd_soc_pcm_runtime *be = dpcm->be;
b073ed4e
KM
1910 struct snd_soc_pcm_stream *codec_stream;
1911 int i;
1912
a4be4187 1913 for_each_rtd_codec_dais(be, i, dai) {
4febced1
JB
1914 /*
1915 * Skip CODECs which don't support the current stream
1916 * type. See soc_pcm_init_runtime_hw() for more details
1917 */
7afecb30 1918 if (!snd_soc_dai_stream_valid(dai, stream))
4febced1
JB
1919 continue;
1920
acf253c1 1921 codec_stream = snd_soc_dai_get_pcm_stream(dai, stream);
b073ed4e 1922
435ffb76 1923 *formats &= codec_stream->formats;
b073ed4e
KM
1924 }
1925 }
b073ed4e
KM
1926}
1927
435ffb76
JB
1928static void dpcm_runtime_merge_chan(struct snd_pcm_substream *substream,
1929 unsigned int *channels_min,
1930 unsigned int *channels_max)
f4c277b8
JW
1931{
1932 struct snd_soc_pcm_runtime *fe = substream->private_data;
1933 struct snd_soc_dpcm *dpcm;
1934 int stream = substream->stream;
1935
1936 if (!fe->dai_link->dpcm_merged_chan)
1937 return;
1938
f4c277b8
JW
1939 /*
1940 * It returns merged BE codec channel;
1941 * if FE want to use it (= dpcm_merged_chan)
1942 */
1943
8d6258a4 1944 for_each_dpcm_be(fe, stream, dpcm) {
f4c277b8 1945 struct snd_soc_pcm_runtime *be = dpcm->be;
f4c277b8 1946 struct snd_soc_pcm_stream *codec_stream;
4f2bd18b 1947 struct snd_soc_pcm_stream *cpu_stream;
19bdcc7a
SN
1948 struct snd_soc_dai *dai;
1949 int i;
4f2bd18b 1950
a4be4187 1951 for_each_rtd_cpu_dais(be, i, dai) {
0e9cf4c4
BL
1952 /*
1953 * Skip CPUs which don't support the current stream
1954 * type. See soc_pcm_init_runtime_hw() for more details
1955 */
1956 if (!snd_soc_dai_stream_valid(dai, stream))
1957 continue;
1958
19bdcc7a 1959 cpu_stream = snd_soc_dai_get_pcm_stream(dai, stream);
4f2bd18b 1960
19bdcc7a
SN
1961 *channels_min = max(*channels_min,
1962 cpu_stream->channels_min);
1963 *channels_max = min(*channels_max,
1964 cpu_stream->channels_max);
1965 }
4f2bd18b
JB
1966
1967 /*
1968 * chan min/max cannot be enforced if there are multiple CODEC
1969 * DAIs connected to a single CPU DAI, use CPU DAI's directly
1970 */
1971 if (be->num_codecs == 1) {
acf253c1 1972 codec_stream = snd_soc_dai_get_pcm_stream(be->codec_dais[0], stream);
f4c277b8
JW
1973
1974 *channels_min = max(*channels_min,
1975 codec_stream->channels_min);
1976 *channels_max = min(*channels_max,
1977 codec_stream->channels_max);
1978 }
1979 }
1980}
1981
baacd8d1
JB
1982static void dpcm_runtime_merge_rate(struct snd_pcm_substream *substream,
1983 unsigned int *rates,
1984 unsigned int *rate_min,
1985 unsigned int *rate_max)
1986{
1987 struct snd_soc_pcm_runtime *fe = substream->private_data;
1988 struct snd_soc_dpcm *dpcm;
1989 int stream = substream->stream;
1990
1991 if (!fe->dai_link->dpcm_merged_rate)
1992 return;
1993
1994 /*
1995 * It returns merged BE codec channel;
1996 * if FE want to use it (= dpcm_merged_chan)
1997 */
1998
8d6258a4 1999 for_each_dpcm_be(fe, stream, dpcm) {
baacd8d1 2000 struct snd_soc_pcm_runtime *be = dpcm->be;
baacd8d1
JB
2001 struct snd_soc_pcm_stream *codec_stream;
2002 struct snd_soc_pcm_stream *cpu_stream;
7afecb30 2003 struct snd_soc_dai *dai;
baacd8d1
JB
2004 int i;
2005
a4be4187 2006 for_each_rtd_cpu_dais(be, i, dai) {
0e9cf4c4
BL
2007 /*
2008 * Skip CPUs which don't support the current stream
2009 * type. See soc_pcm_init_runtime_hw() for more details
2010 */
2011 if (!snd_soc_dai_stream_valid(dai, stream))
2012 continue;
2013
19bdcc7a 2014 cpu_stream = snd_soc_dai_get_pcm_stream(dai, stream);
baacd8d1 2015
19bdcc7a
SN
2016 *rate_min = max(*rate_min, cpu_stream->rate_min);
2017 *rate_max = min_not_zero(*rate_max,
2018 cpu_stream->rate_max);
2019 *rates = snd_pcm_rate_mask_intersect(*rates,
2020 cpu_stream->rates);
2021 }
baacd8d1 2022
a4be4187 2023 for_each_rtd_codec_dais(be, i, dai) {
baacd8d1
JB
2024 /*
2025 * Skip CODECs which don't support the current stream
2026 * type. See soc_pcm_init_runtime_hw() for more details
2027 */
7afecb30 2028 if (!snd_soc_dai_stream_valid(dai, stream))
baacd8d1
JB
2029 continue;
2030
acf253c1 2031 codec_stream = snd_soc_dai_get_pcm_stream(dai, stream);
baacd8d1
JB
2032
2033 *rate_min = max(*rate_min, codec_stream->rate_min);
2034 *rate_max = min_not_zero(*rate_max,
2035 codec_stream->rate_max);
2036 *rates = snd_pcm_rate_mask_intersect(*rates,
2037 codec_stream->rates);
2038 }
2039 }
2040}
2041
45c0a188 2042static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream)
01d7584c
LG
2043{
2044 struct snd_pcm_runtime *runtime = substream->runtime;
2045 struct snd_soc_pcm_runtime *rtd = substream->private_data;
19bdcc7a 2046 struct snd_soc_dai *cpu_dai;
19bdcc7a 2047 int i;
01d7584c 2048
a4be4187 2049 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
0e9cf4c4
BL
2050 /*
2051 * Skip CPUs which don't support the current stream
2052 * type. See soc_pcm_init_runtime_hw() for more details
2053 */
2054 if (!snd_soc_dai_stream_valid(cpu_dai, substream->stream))
2055 continue;
2056
0c9ba720
KM
2057 dpcm_init_runtime_hw(runtime,
2058 snd_soc_dai_get_pcm_stream(cpu_dai,
2059 substream->stream));
19bdcc7a 2060 }
f4c277b8 2061
435ffb76
JB
2062 dpcm_runtime_merge_format(substream, &runtime->hw.formats);
2063 dpcm_runtime_merge_chan(substream, &runtime->hw.channels_min,
2064 &runtime->hw.channels_max);
baacd8d1
JB
2065 dpcm_runtime_merge_rate(substream, &runtime->hw.rates,
2066 &runtime->hw.rate_min, &runtime->hw.rate_max);
01d7584c
LG
2067}
2068
ea9d0d77
TI
2069static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd);
2070
2071/* Set FE's runtime_update state; the state is protected via PCM stream lock
2072 * for avoiding the race with trigger callback.
2073 * If the state is unset and a trigger is pending while the previous operation,
2074 * process the pending trigger action here.
2075 */
2076static void dpcm_set_fe_update_state(struct snd_soc_pcm_runtime *fe,
2077 int stream, enum snd_soc_dpcm_update state)
2078{
2079 struct snd_pcm_substream *substream =
2080 snd_soc_dpcm_get_substream(fe, stream);
2081
2082 snd_pcm_stream_lock_irq(substream);
2083 if (state == SND_SOC_DPCM_UPDATE_NO && fe->dpcm[stream].trigger_pending) {
2084 dpcm_fe_dai_do_trigger(substream,
2085 fe->dpcm[stream].trigger_pending - 1);
2086 fe->dpcm[stream].trigger_pending = 0;
2087 }
2088 fe->dpcm[stream].runtime_update = state;
2089 snd_pcm_stream_unlock_irq(substream);
2090}
2091
906c7d69
PL
2092static int dpcm_apply_symmetry(struct snd_pcm_substream *fe_substream,
2093 int stream)
2094{
2095 struct snd_soc_dpcm *dpcm;
2096 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
19bdcc7a 2097 struct snd_soc_dai *fe_cpu_dai;
906c7d69 2098 int err;
19bdcc7a 2099 int i;
906c7d69
PL
2100
2101 /* apply symmetry for FE */
2102 if (soc_pcm_has_symmetry(fe_substream))
2103 fe_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;
2104
a4be4187 2105 for_each_rtd_cpu_dais (fe, i, fe_cpu_dai) {
19bdcc7a
SN
2106 /* Symmetry only applies if we've got an active stream. */
2107 if (fe_cpu_dai->active) {
2108 err = soc_pcm_apply_symmetry(fe_substream, fe_cpu_dai);
2109 if (err < 0)
2110 return err;
2111 }
906c7d69
PL
2112 }
2113
2114 /* apply symmetry for BE */
8d6258a4 2115 for_each_dpcm_be(fe, stream, dpcm) {
906c7d69
PL
2116 struct snd_soc_pcm_runtime *be = dpcm->be;
2117 struct snd_pcm_substream *be_substream =
2118 snd_soc_dpcm_get_substream(be, stream);
6246f283 2119 struct snd_soc_pcm_runtime *rtd;
0b7990e3 2120 struct snd_soc_dai *codec_dai;
19bdcc7a 2121 struct snd_soc_dai *cpu_dai;
906c7d69
PL
2122 int i;
2123
6246f283
JB
2124 /* A backend may not have the requested substream */
2125 if (!be_substream)
2126 continue;
2127
2128 rtd = be_substream->private_data;
f1176614
JK
2129 if (rtd->dai_link->be_hw_params_fixup)
2130 continue;
2131
906c7d69
PL
2132 if (soc_pcm_has_symmetry(be_substream))
2133 be_substream->runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;
2134
2135 /* Symmetry only applies if we've got an active stream. */
a4be4187 2136 for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
19bdcc7a
SN
2137 if (cpu_dai->active) {
2138 err = soc_pcm_apply_symmetry(fe_substream,
2139 cpu_dai);
2140 if (err < 0)
2141 return err;
2142 }
906c7d69
PL
2143 }
2144
a4be4187 2145 for_each_rtd_codec_dais(rtd, i, codec_dai) {
0b7990e3 2146 if (codec_dai->active) {
99bcedbd 2147 err = soc_pcm_apply_symmetry(fe_substream,
0b7990e3 2148 codec_dai);
906c7d69
PL
2149 if (err < 0)
2150 return err;
2151 }
2152 }
2153 }
2154
2155 return 0;
2156}
2157
01d7584c
LG
2158static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
2159{
2160 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
2161 struct snd_pcm_runtime *runtime = fe_substream->runtime;
2162 int stream = fe_substream->stream, ret = 0;
2163
ea9d0d77 2164 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
01d7584c 2165
25c2f515 2166 ret = dpcm_be_dai_startup(fe, stream);
01d7584c 2167 if (ret < 0) {
103d84a3 2168 dev_err(fe->dev,"ASoC: failed to start some BEs %d\n", ret);
01d7584c
LG
2169 goto be_err;
2170 }
2171
103d84a3 2172 dev_dbg(fe->dev, "ASoC: open FE %s\n", fe->dai_link->name);
01d7584c
LG
2173
2174 /* start the DAI frontend */
2175 ret = soc_pcm_open(fe_substream);
2176 if (ret < 0) {
103d84a3 2177 dev_err(fe->dev,"ASoC: failed to start FE %d\n", ret);
01d7584c
LG
2178 goto unwind;
2179 }
2180
2181 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
2182
2183 dpcm_set_fe_runtime(fe_substream);
2184 snd_pcm_limit_hw_rates(runtime);
2185
906c7d69 2186 ret = dpcm_apply_symmetry(fe_substream, stream);
8a01fbf0 2187 if (ret < 0)
906c7d69
PL
2188 dev_err(fe->dev, "ASoC: failed to apply dpcm symmetry %d\n",
2189 ret);
01d7584c
LG
2190
2191unwind:
8a01fbf0
KM
2192 if (ret < 0)
2193 dpcm_be_dai_startup_unwind(fe, stream);
01d7584c 2194be_err:
ea9d0d77 2195 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
01d7584c
LG
2196 return ret;
2197}
2198
23607025 2199int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
01d7584c
LG
2200{
2201 struct snd_soc_dpcm *dpcm;
2202
2203 /* only shutdown BEs that are either sinks or sources to this FE DAI */
8d6258a4 2204 for_each_dpcm_be(fe, stream, dpcm) {
01d7584c
LG
2205
2206 struct snd_soc_pcm_runtime *be = dpcm->be;
2207 struct snd_pcm_substream *be_substream =
2208 snd_soc_dpcm_get_substream(be, stream);
2209
2210 /* is this op for this BE ? */
2211 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
2212 continue;
2213
2214 if (be->dpcm[stream].users == 0)
103d84a3 2215 dev_err(be->dev, "ASoC: no users %s at close - state %d\n",
01d7584c
LG
2216 stream ? "capture" : "playback",
2217 be->dpcm[stream].state);
2218
2219 if (--be->dpcm[stream].users != 0)
2220 continue;
2221
2222 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
9c0ac70a
KCC
2223 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)) {
2224 soc_pcm_hw_free(be_substream);
2225 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
2226 }
01d7584c 2227
103d84a3 2228 dev_dbg(be->dev, "ASoC: close BE %s\n",
94d215cc 2229 be->dai_link->name);
01d7584c
LG
2230
2231 soc_pcm_close(be_substream);
2232 be_substream->runtime = NULL;
2233
2234 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
2235 }
2236 return 0;
2237}
2238
2239static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream)
2240{
2241 struct snd_soc_pcm_runtime *fe = substream->private_data;
2242 int stream = substream->stream;
2243
ea9d0d77 2244 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
01d7584c
LG
2245
2246 /* shutdown the BEs */
25c2f515 2247 dpcm_be_dai_shutdown(fe, stream);
01d7584c 2248
103d84a3 2249 dev_dbg(fe->dev, "ASoC: close FE %s\n", fe->dai_link->name);
01d7584c
LG
2250
2251 /* now shutdown the frontend */
2252 soc_pcm_close(substream);
2253
2254 /* run the stream event for each BE */
1c531230 2255 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
01d7584c
LG
2256
2257 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
ea9d0d77 2258 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
01d7584c
LG
2259 return 0;
2260}
2261
23607025 2262int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream)
01d7584c
LG
2263{
2264 struct snd_soc_dpcm *dpcm;
2265
2266 /* only hw_params backends that are either sinks or sources
2267 * to this frontend DAI */
8d6258a4 2268 for_each_dpcm_be(fe, stream, dpcm) {
01d7584c
LG
2269
2270 struct snd_soc_pcm_runtime *be = dpcm->be;
2271 struct snd_pcm_substream *be_substream =
2272 snd_soc_dpcm_get_substream(be, stream);
2273
2274 /* is this op for this BE ? */
2275 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
2276 continue;
2277
2278 /* only free hw when no longer used - check all FEs */
2279 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
2280 continue;
2281
36fba62c
QZ
2282 /* do not free hw if this BE is used by other FE */
2283 if (be->dpcm[stream].users > 1)
2284 continue;
2285
01d7584c
LG
2286 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
2287 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
2288 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
08b27848 2289 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) &&
5e82d2be
VK
2290 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) &&
2291 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND))
01d7584c
LG
2292 continue;
2293
103d84a3 2294 dev_dbg(be->dev, "ASoC: hw_free BE %s\n",
94d215cc 2295 be->dai_link->name);
01d7584c
LG
2296
2297 soc_pcm_hw_free(be_substream);
2298
2299 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
2300 }
2301
2302 return 0;
2303}
2304
45c0a188 2305static int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream)
01d7584c
LG
2306{
2307 struct snd_soc_pcm_runtime *fe = substream->private_data;
2308 int err, stream = substream->stream;
2309
2310 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
ea9d0d77 2311 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
01d7584c 2312
103d84a3 2313 dev_dbg(fe->dev, "ASoC: hw_free FE %s\n", fe->dai_link->name);
01d7584c
LG
2314
2315 /* call hw_free on the frontend */
2316 err = soc_pcm_hw_free(substream);
2317 if (err < 0)
103d84a3 2318 dev_err(fe->dev,"ASoC: hw_free FE %s failed\n",
01d7584c
LG
2319 fe->dai_link->name);
2320
2321 /* only hw_params backends that are either sinks or sources
2322 * to this frontend DAI */
2323 err = dpcm_be_dai_hw_free(fe, stream);
2324
2325 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
ea9d0d77 2326 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
01d7584c
LG
2327
2328 mutex_unlock(&fe->card->mutex);
2329 return 0;
2330}
2331
23607025 2332int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream)
01d7584c
LG
2333{
2334 struct snd_soc_dpcm *dpcm;
2335 int ret;
2336
8d6258a4 2337 for_each_dpcm_be(fe, stream, dpcm) {
01d7584c
LG
2338
2339 struct snd_soc_pcm_runtime *be = dpcm->be;
2340 struct snd_pcm_substream *be_substream =
2341 snd_soc_dpcm_get_substream(be, stream);
2342
2343 /* is this op for this BE ? */
2344 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
2345 continue;
2346
01d7584c
LG
2347 /* copy params for each dpcm */
2348 memcpy(&dpcm->hw_params, &fe->dpcm[stream].hw_params,
2349 sizeof(struct snd_pcm_hw_params));
2350
2351 /* perform any hw_params fixups */
2352 if (be->dai_link->be_hw_params_fixup) {
2353 ret = be->dai_link->be_hw_params_fixup(be,
2354 &dpcm->hw_params);
2355 if (ret < 0) {
2356 dev_err(be->dev,
103d84a3 2357 "ASoC: hw_params BE fixup failed %d\n",
01d7584c
LG
2358 ret);
2359 goto unwind;
2360 }
2361 }
2362
ae061d2a
LY
2363 /* copy the fixed-up hw params for BE dai */
2364 memcpy(&be->dpcm[stream].hw_params, &dpcm->hw_params,
2365 sizeof(struct snd_pcm_hw_params));
2366
b0639bd2
KM
2367 /* only allow hw_params() if no connected FEs are running */
2368 if (!snd_soc_dpcm_can_be_params(fe, be, stream))
2369 continue;
2370
2371 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
2372 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
2373 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE))
2374 continue;
2375
2376 dev_dbg(be->dev, "ASoC: hw_params BE %s\n",
94d215cc 2377 be->dai_link->name);
b0639bd2 2378
01d7584c
LG
2379 ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params);
2380 if (ret < 0) {
2381 dev_err(dpcm->be->dev,
103d84a3 2382 "ASoC: hw_params BE failed %d\n", ret);
01d7584c
LG
2383 goto unwind;
2384 }
2385
2386 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
2387 }
2388 return 0;
2389
2390unwind:
2391 /* disable any enabled and non active backends */
8d6258a4 2392 for_each_dpcm_be_rollback(fe, stream, dpcm) {
01d7584c
LG
2393 struct snd_soc_pcm_runtime *be = dpcm->be;
2394 struct snd_pcm_substream *be_substream =
2395 snd_soc_dpcm_get_substream(be, stream);
2396
2397 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
2398 continue;
2399
2400 /* only allow hw_free() if no connected FEs are running */
2401 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
2402 continue;
2403
2404 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
2405 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
2406 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
2407 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
2408 continue;
2409
2410 soc_pcm_hw_free(be_substream);
2411 }
2412
2413 return ret;
2414}
2415
45c0a188
MB
2416static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream,
2417 struct snd_pcm_hw_params *params)
01d7584c
LG
2418{
2419 struct snd_soc_pcm_runtime *fe = substream->private_data;
2420 int ret, stream = substream->stream;
2421
2422 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
ea9d0d77 2423 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
01d7584c 2424
25c2f515 2425 memcpy(&fe->dpcm[stream].hw_params, params,
01d7584c 2426 sizeof(struct snd_pcm_hw_params));
25c2f515 2427 ret = dpcm_be_dai_hw_params(fe, stream);
01d7584c 2428 if (ret < 0) {
103d84a3 2429 dev_err(fe->dev,"ASoC: hw_params BE failed %d\n", ret);
01d7584c
LG
2430 goto out;
2431 }
2432
103d84a3 2433 dev_dbg(fe->dev, "ASoC: hw_params FE %s rate %d chan %x fmt %d\n",
01d7584c
LG
2434 fe->dai_link->name, params_rate(params),
2435 params_channels(params), params_format(params));
2436
2437 /* call hw_params on the frontend */
2438 ret = soc_pcm_hw_params(substream, params);
2439 if (ret < 0) {
103d84a3 2440 dev_err(fe->dev,"ASoC: hw_params FE failed %d\n", ret);
01d7584c
LG
2441 dpcm_be_dai_hw_free(fe, stream);
2442 } else
2443 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
2444
2445out:
ea9d0d77 2446 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
01d7584c
LG
2447 mutex_unlock(&fe->card->mutex);
2448 return ret;
2449}
2450
2451static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm,
2452 struct snd_pcm_substream *substream, int cmd)
2453{
2454 int ret;
2455
103d84a3 2456 dev_dbg(dpcm->be->dev, "ASoC: trigger BE %s cmd %d\n",
94d215cc 2457 dpcm->be->dai_link->name, cmd);
01d7584c
LG
2458
2459 ret = soc_pcm_trigger(substream, cmd);
2460 if (ret < 0)
103d84a3 2461 dev_err(dpcm->be->dev,"ASoC: trigger BE failed %d\n", ret);
01d7584c
LG
2462
2463 return ret;
2464}
2465
23607025 2466int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
45c0a188 2467 int cmd)
01d7584c
LG
2468{
2469 struct snd_soc_dpcm *dpcm;
2470 int ret = 0;
2471
8d6258a4 2472 for_each_dpcm_be(fe, stream, dpcm) {
01d7584c
LG
2473
2474 struct snd_soc_pcm_runtime *be = dpcm->be;
2475 struct snd_pcm_substream *be_substream =
2476 snd_soc_dpcm_get_substream(be, stream);
2477
2478 /* is this op for this BE ? */
2479 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
2480 continue;
2481
2482 switch (cmd) {
2483 case SNDRV_PCM_TRIGGER_START:
2484 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
2485 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
2486 continue;
2487
2488 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
2489 if (ret)
2490 return ret;
2491
2492 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
2493 break;
2494 case SNDRV_PCM_TRIGGER_RESUME:
2495 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND))
2496 continue;
2497
2498 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
2499 if (ret)
2500 return ret;
2501
2502 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
2503 break;
2504 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
2505 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
2506 continue;
2507
2508 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
2509 if (ret)
2510 return ret;
2511
2512 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
2513 break;
2514 case SNDRV_PCM_TRIGGER_STOP:
2515 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
2516 continue;
2517
2518 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
2519 continue;
2520
2521 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
2522 if (ret)
2523 return ret;
2524
2525 be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
2526 break;
2527 case SNDRV_PCM_TRIGGER_SUSPEND:
868a6ca8 2528 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
01d7584c
LG
2529 continue;
2530
2531 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
2532 continue;
2533
2534 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
2535 if (ret)
2536 return ret;
2537
2538 be->dpcm[stream].state = SND_SOC_DPCM_STATE_SUSPEND;
2539 break;
2540 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
2541 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
2542 continue;
2543
2544 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
2545 continue;
2546
2547 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
2548 if (ret)
2549 return ret;
2550
2551 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
2552 break;
2553 }
2554 }
2555
2556 return ret;
2557}
2558EXPORT_SYMBOL_GPL(dpcm_be_dai_trigger);
2559
acbf2774
RS
2560static int dpcm_dai_trigger_fe_be(struct snd_pcm_substream *substream,
2561 int cmd, bool fe_first)
2562{
2563 struct snd_soc_pcm_runtime *fe = substream->private_data;
2564 int ret;
2565
2566 /* call trigger on the frontend before the backend. */
2567 if (fe_first) {
2568 dev_dbg(fe->dev, "ASoC: pre trigger FE %s cmd %d\n",
2569 fe->dai_link->name, cmd);
2570
2571 ret = soc_pcm_trigger(substream, cmd);
2572 if (ret < 0)
2573 return ret;
2574
2575 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
2576 return ret;
2577 }
2578
2579 /* call trigger on the frontend after the backend. */
2580 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
2581 if (ret < 0)
2582 return ret;
2583
2584 dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n",
2585 fe->dai_link->name, cmd);
2586
2587 ret = soc_pcm_trigger(substream, cmd);
2588
2589 return ret;
2590}
2591
ea9d0d77 2592static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd)
01d7584c
LG
2593{
2594 struct snd_soc_pcm_runtime *fe = substream->private_data;
acbf2774
RS
2595 int stream = substream->stream;
2596 int ret = 0;
01d7584c
LG
2597 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
2598
2599 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
2600
2601 switch (trigger) {
2602 case SND_SOC_DPCM_TRIGGER_PRE:
acbf2774
RS
2603 switch (cmd) {
2604 case SNDRV_PCM_TRIGGER_START:
2605 case SNDRV_PCM_TRIGGER_RESUME:
2606 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
2607 ret = dpcm_dai_trigger_fe_be(substream, cmd, true);
2608 break;
2609 case SNDRV_PCM_TRIGGER_STOP:
2610 case SNDRV_PCM_TRIGGER_SUSPEND:
2611 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
2612 ret = dpcm_dai_trigger_fe_be(substream, cmd, false);
2613 break;
2614 default:
2615 ret = -EINVAL;
2616 break;
01d7584c 2617 }
01d7584c
LG
2618 break;
2619 case SND_SOC_DPCM_TRIGGER_POST:
acbf2774
RS
2620 switch (cmd) {
2621 case SNDRV_PCM_TRIGGER_START:
2622 case SNDRV_PCM_TRIGGER_RESUME:
2623 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
2624 ret = dpcm_dai_trigger_fe_be(substream, cmd, false);
2625 break;
2626 case SNDRV_PCM_TRIGGER_STOP:
2627 case SNDRV_PCM_TRIGGER_SUSPEND:
2628 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
2629 ret = dpcm_dai_trigger_fe_be(substream, cmd, true);
2630 break;
2631 default:
2632 ret = -EINVAL;
2633 break;
01d7584c 2634 }
01d7584c 2635 break;
07bf84aa
LG
2636 case SND_SOC_DPCM_TRIGGER_BESPOKE:
2637 /* bespoke trigger() - handles both FE and BEs */
2638
103d84a3 2639 dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd %d\n",
07bf84aa
LG
2640 fe->dai_link->name, cmd);
2641
2642 ret = soc_pcm_bespoke_trigger(substream, cmd);
07bf84aa 2643 break;
01d7584c 2644 default:
103d84a3 2645 dev_err(fe->dev, "ASoC: invalid trigger cmd %d for %s\n", cmd,
01d7584c
LG
2646 fe->dai_link->name);
2647 ret = -EINVAL;
2648 goto out;
2649 }
2650
acbf2774
RS
2651 if (ret < 0) {
2652 dev_err(fe->dev, "ASoC: trigger FE cmd: %d failed: %d\n",
2653 cmd, ret);
2654 goto out;
2655 }
2656
01d7584c
LG
2657 switch (cmd) {
2658 case SNDRV_PCM_TRIGGER_START:
2659 case SNDRV_PCM_TRIGGER_RESUME:
2660 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
2661 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
2662 break;
2663 case SNDRV_PCM_TRIGGER_STOP:
2664 case SNDRV_PCM_TRIGGER_SUSPEND:
01d7584c
LG
2665 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
2666 break;
9f169b9f
PL
2667 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
2668 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
2669 break;
01d7584c
LG
2670 }
2671
2672out:
2673 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
2674 return ret;
2675}
2676
ea9d0d77
TI
2677static int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd)
2678{
2679 struct snd_soc_pcm_runtime *fe = substream->private_data;
2680 int stream = substream->stream;
2681
2682 /* if FE's runtime_update is already set, we're in race;
2683 * process this trigger later at exit
2684 */
2685 if (fe->dpcm[stream].runtime_update != SND_SOC_DPCM_UPDATE_NO) {
2686 fe->dpcm[stream].trigger_pending = cmd + 1;
2687 return 0; /* delayed, assuming it's successful */
2688 }
2689
2690 /* we're alone, let's trigger */
2691 return dpcm_fe_dai_do_trigger(substream, cmd);
2692}
2693
23607025 2694int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream)
01d7584c
LG
2695{
2696 struct snd_soc_dpcm *dpcm;
2697 int ret = 0;
2698
8d6258a4 2699 for_each_dpcm_be(fe, stream, dpcm) {
01d7584c
LG
2700
2701 struct snd_soc_pcm_runtime *be = dpcm->be;
2702 struct snd_pcm_substream *be_substream =
2703 snd_soc_dpcm_get_substream(be, stream);
2704
2705 /* is this op for this BE ? */
2706 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
2707 continue;
2708
2709 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
95f444dc 2710 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) &&
5087a8f1
LY
2711 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND) &&
2712 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
01d7584c
LG
2713 continue;
2714
103d84a3 2715 dev_dbg(be->dev, "ASoC: prepare BE %s\n",
94d215cc 2716 be->dai_link->name);
01d7584c
LG
2717
2718 ret = soc_pcm_prepare(be_substream);
2719 if (ret < 0) {
103d84a3 2720 dev_err(be->dev, "ASoC: backend prepare failed %d\n",
01d7584c
LG
2721 ret);
2722 break;
2723 }
2724
2725 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
2726 }
2727 return ret;
2728}
2729
45c0a188 2730static int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream)
01d7584c
LG
2731{
2732 struct snd_soc_pcm_runtime *fe = substream->private_data;
2733 int stream = substream->stream, ret = 0;
2734
2735 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
2736
103d84a3 2737 dev_dbg(fe->dev, "ASoC: prepare FE %s\n", fe->dai_link->name);
01d7584c 2738
ea9d0d77 2739 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_FE);
01d7584c
LG
2740
2741 /* there is no point preparing this FE if there are no BEs */
2742 if (list_empty(&fe->dpcm[stream].be_clients)) {
103d84a3 2743 dev_err(fe->dev, "ASoC: no backend DAIs enabled for %s\n",
01d7584c
LG
2744 fe->dai_link->name);
2745 ret = -EINVAL;
2746 goto out;
2747 }
2748
25c2f515 2749 ret = dpcm_be_dai_prepare(fe, stream);
01d7584c
LG
2750 if (ret < 0)
2751 goto out;
2752
2753 /* call prepare on the frontend */
2754 ret = soc_pcm_prepare(substream);
2755 if (ret < 0) {
103d84a3 2756 dev_err(fe->dev,"ASoC: prepare FE %s failed\n",
01d7584c
LG
2757 fe->dai_link->name);
2758 goto out;
2759 }
2760
2761 /* run the stream event for each BE */
2762 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
2763 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
2764
2765out:
ea9d0d77 2766 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
01d7584c
LG
2767 mutex_unlock(&fe->card->mutex);
2768
2769 return ret;
2770}
2771
618dae11
LG
2772static int dpcm_run_update_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
2773{
07bf84aa
LG
2774 struct snd_pcm_substream *substream =
2775 snd_soc_dpcm_get_substream(fe, stream);
2776 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
618dae11
LG
2777 int err;
2778
103d84a3 2779 dev_dbg(fe->dev, "ASoC: runtime %s close on FE %s\n",
618dae11
LG
2780 stream ? "capture" : "playback", fe->dai_link->name);
2781
07bf84aa
LG
2782 if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) {
2783 /* call bespoke trigger - FE takes care of all BE triggers */
103d84a3 2784 dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd stop\n",
07bf84aa
LG
2785 fe->dai_link->name);
2786
2787 err = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_STOP);
2788 if (err < 0)
103d84a3 2789 dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err);
07bf84aa 2790 } else {
103d84a3 2791 dev_dbg(fe->dev, "ASoC: trigger FE %s cmd stop\n",
07bf84aa
LG
2792 fe->dai_link->name);
2793
2794 err = dpcm_be_dai_trigger(fe, stream, SNDRV_PCM_TRIGGER_STOP);
2795 if (err < 0)
103d84a3 2796 dev_err(fe->dev,"ASoC: trigger FE failed %d\n", err);
07bf84aa 2797 }
618dae11
LG
2798
2799 err = dpcm_be_dai_hw_free(fe, stream);
2800 if (err < 0)
103d84a3 2801 dev_err(fe->dev,"ASoC: hw_free FE failed %d\n", err);
618dae11
LG
2802
2803 err = dpcm_be_dai_shutdown(fe, stream);
2804 if (err < 0)
103d84a3 2805 dev_err(fe->dev,"ASoC: shutdown FE failed %d\n", err);
618dae11
LG
2806
2807 /* run the stream event for each BE */
2808 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_NOP);
2809
2810 return 0;
2811}
2812
2813static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
2814{
07bf84aa
LG
2815 struct snd_pcm_substream *substream =
2816 snd_soc_dpcm_get_substream(fe, stream);
618dae11 2817 struct snd_soc_dpcm *dpcm;
07bf84aa 2818 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
618dae11 2819 int ret;
a9764869 2820 unsigned long flags;
618dae11 2821
103d84a3 2822 dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n",
618dae11
LG
2823 stream ? "capture" : "playback", fe->dai_link->name);
2824
2825 /* Only start the BE if the FE is ready */
2826 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_HW_FREE ||
2827 fe->dpcm[stream].state == SND_SOC_DPCM_STATE_CLOSE)
2828 return -EINVAL;
2829
2830 /* startup must always be called for new BEs */
2831 ret = dpcm_be_dai_startup(fe, stream);
fffc0ca2 2832 if (ret < 0)
618dae11 2833 goto disconnect;
618dae11
LG
2834
2835 /* keep going if FE state is > open */
2836 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_OPEN)
2837 return 0;
01d7584c 2838
618dae11 2839 ret = dpcm_be_dai_hw_params(fe, stream);
fffc0ca2 2840 if (ret < 0)
618dae11 2841 goto close;
618dae11
LG
2842
2843 /* keep going if FE state is > hw_params */
2844 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_HW_PARAMS)
2845 return 0;
2846
2847
2848 ret = dpcm_be_dai_prepare(fe, stream);
fffc0ca2 2849 if (ret < 0)
618dae11 2850 goto hw_free;
618dae11
LG
2851
2852 /* run the stream event for each BE */
2853 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_NOP);
2854
2855 /* keep going if FE state is > prepare */
2856 if (fe->dpcm[stream].state == SND_SOC_DPCM_STATE_PREPARE ||
2857 fe->dpcm[stream].state == SND_SOC_DPCM_STATE_STOP)
2858 return 0;
2859
07bf84aa
LG
2860 if (trigger == SND_SOC_DPCM_TRIGGER_BESPOKE) {
2861 /* call trigger on the frontend - FE takes care of all BE triggers */
103d84a3 2862 dev_dbg(fe->dev, "ASoC: bespoke trigger FE %s cmd start\n",
07bf84aa 2863 fe->dai_link->name);
618dae11 2864
07bf84aa
LG
2865 ret = soc_pcm_bespoke_trigger(substream, SNDRV_PCM_TRIGGER_START);
2866 if (ret < 0) {
103d84a3 2867 dev_err(fe->dev,"ASoC: bespoke trigger FE failed %d\n", ret);
07bf84aa
LG
2868 goto hw_free;
2869 }
2870 } else {
103d84a3 2871 dev_dbg(fe->dev, "ASoC: trigger FE %s cmd start\n",
07bf84aa
LG
2872 fe->dai_link->name);
2873
2874 ret = dpcm_be_dai_trigger(fe, stream,
2875 SNDRV_PCM_TRIGGER_START);
2876 if (ret < 0) {
103d84a3 2877 dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret);
07bf84aa
LG
2878 goto hw_free;
2879 }
618dae11
LG
2880 }
2881
2882 return 0;
2883
2884hw_free:
2885 dpcm_be_dai_hw_free(fe, stream);
2886close:
2887 dpcm_be_dai_shutdown(fe, stream);
2888disconnect:
2889 /* disconnect any non started BEs */
a9764869 2890 spin_lock_irqsave(&fe->card->dpcm_lock, flags);
8d6258a4 2891 for_each_dpcm_be(fe, stream, dpcm) {
618dae11
LG
2892 struct snd_soc_pcm_runtime *be = dpcm->be;
2893 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
2894 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
2895 }
a9764869 2896 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
618dae11
LG
2897
2898 return ret;
2899}
2900
de15d7ff 2901static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new)
618dae11 2902{
de15d7ff 2903 struct snd_soc_dapm_widget_list *list;
7083f877 2904 int stream;
de15d7ff 2905 int count, paths;
580dff36 2906 int ret;
618dae11 2907
6e1276a5
BL
2908 if (fe->num_cpus > 1) {
2909 dev_err(fe->dev,
2910 "%s doesn't support Multi CPU yet\n", __func__);
2911 return -EINVAL;
2912 }
2913
de15d7ff
JB
2914 if (!fe->dai_link->dynamic)
2915 return 0;
618dae11 2916
de15d7ff
JB
2917 /* only check active links */
2918 if (!fe->cpu_dai->active)
2919 return 0;
618dae11 2920
de15d7ff
JB
2921 /* DAPM sync will call this to update DSP paths */
2922 dev_dbg(fe->dev, "ASoC: DPCM %s runtime update for FE %s\n",
2923 new ? "new" : "old", fe->dai_link->name);
618dae11 2924
7083f877 2925 for_each_pcm_streams(stream) {
618dae11 2926
7083f877
KM
2927 /* skip if FE doesn't have playback/capture capability */
2928 if (!snd_soc_dai_stream_valid(fe->cpu_dai, stream) ||
2929 !snd_soc_dai_stream_valid(fe->codec_dai, stream))
2930 continue;
de15d7ff 2931
7083f877
KM
2932 /* skip if FE isn't currently playing/capturing */
2933 if (!fe->cpu_dai->stream_active[stream] ||
2934 !fe->codec_dai->stream_active[stream])
2935 continue;
075207d2 2936
7083f877
KM
2937 paths = dpcm_path_get(fe, stream, &list);
2938 if (paths < 0) {
2939 dev_warn(fe->dev, "ASoC: %s no valid %s path\n",
2940 fe->dai_link->name,
2941 stream == SNDRV_PCM_STREAM_PLAYBACK ?
2942 "playback" : "capture");
2943 return paths;
2944 }
618dae11 2945
7083f877
KM
2946 /* update any playback/capture paths */
2947 count = dpcm_process_paths(fe, stream, &list, new);
2948 if (count) {
580dff36 2949 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_BE);
7083f877 2950 if (new)
580dff36 2951 ret = dpcm_run_update_startup(fe, stream);
7083f877 2952 else
580dff36
KM
2953 ret = dpcm_run_update_shutdown(fe, stream);
2954 if (ret < 0)
2955 dev_err(fe->dev, "ASoC: failed to shutdown some BEs\n");
2956 dpcm_set_fe_update_state(fe, stream, SND_SOC_DPCM_UPDATE_NO);
618dae11 2957
7083f877
KM
2958 dpcm_clear_pending_state(fe, stream);
2959 dpcm_be_disconnect(fe, stream);
2960 }
618dae11 2961
7083f877 2962 dpcm_path_put(&list);
618dae11
LG
2963 }
2964
618dae11
LG
2965 return 0;
2966}
de15d7ff
JB
2967
2968/* Called by DAPM mixer/mux changes to update audio routing between PCMs and
2969 * any DAI links.
2970 */
2971int soc_dpcm_runtime_update(struct snd_soc_card *card)
2972{
2973 struct snd_soc_pcm_runtime *fe;
2974 int ret = 0;
2975
2976 mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
2977 /* shutdown all old paths first */
bcb1fd1f 2978 for_each_card_rtds(card, fe) {
de15d7ff
JB
2979 ret = soc_dpcm_fe_runtime_update(fe, 0);
2980 if (ret)
2981 goto out;
2982 }
2983
2984 /* bring new paths up */
bcb1fd1f 2985 for_each_card_rtds(card, fe) {
de15d7ff
JB
2986 ret = soc_dpcm_fe_runtime_update(fe, 1);
2987 if (ret)
2988 goto out;
2989 }
2990
2991out:
2992 mutex_unlock(&card->mutex);
2993 return ret;
2994}
01d7584c 2995
265694b6 2996static void dpcm_fe_dai_cleanup(struct snd_pcm_substream *fe_substream)
01d7584c
LG
2997{
2998 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
2999 struct snd_soc_dpcm *dpcm;
265694b6 3000 int stream = fe_substream->stream;
30fca26f
KM
3001
3002 /* mark FE's links ready to prune */
3003 for_each_dpcm_be(fe, stream, dpcm)
3004 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
3005
3006 dpcm_be_disconnect(fe, stream);
3007
3008 fe->dpcm[stream].runtime = NULL;
265694b6
KM
3009}
3010
3011static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
3012{
3013 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
3014 int ret;
3015
3016 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
3017 ret = dpcm_fe_dai_shutdown(fe_substream);
3018
3019 dpcm_fe_dai_cleanup(fe_substream);
3020
30fca26f
KM
3021 mutex_unlock(&fe->card->mutex);
3022 return ret;
3023}
3024
45c0a188 3025static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream)
01d7584c
LG
3026{
3027 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
01d7584c
LG
3028 struct snd_soc_dapm_widget_list *list;
3029 int ret;
3030 int stream = fe_substream->stream;
3031
3032 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
3033 fe->dpcm[stream].runtime = fe_substream->runtime;
3034
8f70e515
QZ
3035 ret = dpcm_path_get(fe, stream, &list);
3036 if (ret < 0) {
cae06eb9 3037 goto open_end;
8f70e515 3038 } else if (ret == 0) {
103d84a3 3039 dev_dbg(fe->dev, "ASoC: %s no valid %s route\n",
01d7584c 3040 fe->dai_link->name, stream ? "capture" : "playback");
01d7584c
LG
3041 }
3042
3043 /* calculate valid and active FE <-> BE dpcms */
3044 dpcm_process_paths(fe, stream, &list, 1);
3045
3046 ret = dpcm_fe_dai_startup(fe_substream);
265694b6
KM
3047 if (ret < 0)
3048 dpcm_fe_dai_cleanup(fe_substream);
01d7584c
LG
3049
3050 dpcm_clear_pending_state(fe, stream);
3051 dpcm_path_put(&list);
cae06eb9 3052open_end:
01d7584c
LG
3053 mutex_unlock(&fe->card->mutex);
3054 return ret;
3055}
3056
ddee627c
LG
3057/* create a new pcm */
3058int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
3059{
2e5894d7 3060 struct snd_soc_dai *codec_dai;
19bdcc7a 3061 struct snd_soc_dai *cpu_dai;
2b544dd7 3062 struct snd_soc_component *component;
ddee627c
LG
3063 struct snd_pcm *pcm;
3064 char new_name[64];
3065 int ret = 0, playback = 0, capture = 0;
2e5894d7 3066 int i;
ddee627c 3067
01d7584c 3068 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) {
1e9de42f
LG
3069 playback = rtd->dai_link->dpcm_playback;
3070 capture = rtd->dai_link->dpcm_capture;
01d7584c 3071 } else {
a342031c 3072 /* Adapt stream for codec2codec links */
a4877a6f
SG
3073 int cpu_capture = rtd->dai_link->params ?
3074 SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
3075 int cpu_playback = rtd->dai_link->params ?
3076 SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
a342031c 3077
a4be4187 3078 for_each_rtd_codec_dais(rtd, i, codec_dai) {
19bdcc7a
SN
3079 if (rtd->num_cpus == 1) {
3080 cpu_dai = rtd->cpu_dais[0];
3081 } else if (rtd->num_cpus == rtd->num_codecs) {
3082 cpu_dai = rtd->cpu_dais[i];
3083 } else {
3084 dev_err(rtd->card->dev,
3085 "N cpus to M codecs link is not supported yet\n");
3086 return -EINVAL;
3087 }
3088
467fece8 3089 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
a4877a6f 3090 snd_soc_dai_stream_valid(cpu_dai, cpu_playback))
2e5894d7 3091 playback = 1;
467fece8 3092 if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
a4877a6f 3093 snd_soc_dai_stream_valid(cpu_dai, cpu_capture))
2e5894d7
BC
3094 capture = 1;
3095 }
01d7584c
LG
3096 }
3097
d6bead02
FE
3098 if (rtd->dai_link->playback_only) {
3099 playback = 1;
3100 capture = 0;
3101 }
3102
3103 if (rtd->dai_link->capture_only) {
3104 playback = 0;
3105 capture = 1;
3106 }
3107
01d7584c 3108 /* create the PCM */
a342031c
JB
3109 if (rtd->dai_link->params) {
3110 snprintf(new_name, sizeof(new_name), "codec2codec(%s)",
3111 rtd->dai_link->stream_name);
3112
3113 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
3114 playback, capture, &pcm);
3115 } else if (rtd->dai_link->no_pcm) {
01d7584c
LG
3116 snprintf(new_name, sizeof(new_name), "(%s)",
3117 rtd->dai_link->stream_name);
3118
3119 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
3120 playback, capture, &pcm);
3121 } else {
3122 if (rtd->dai_link->dynamic)
3123 snprintf(new_name, sizeof(new_name), "%s (*)",
3124 rtd->dai_link->stream_name);
3125 else
3126 snprintf(new_name, sizeof(new_name), "%s %s-%d",
2e5894d7
BC
3127 rtd->dai_link->stream_name,
3128 (rtd->num_codecs > 1) ?
3129 "multicodec" : rtd->codec_dai->name, num);
01d7584c
LG
3130
3131 ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback,
3132 capture, &pcm);
3133 }
ddee627c 3134 if (ret < 0) {
103d84a3 3135 dev_err(rtd->card->dev, "ASoC: can't create pcm for %s\n",
5cb9b748 3136 rtd->dai_link->name);
ddee627c
LG
3137 return ret;
3138 }
103d84a3 3139 dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name);
ddee627c
LG
3140
3141 /* DAPM dai link stream work */
a342031c 3142 if (rtd->dai_link->params)
4bf2e385 3143 rtd->close_delayed_work_func = codec2codec_close_delayed_work;
a342031c 3144 else
83f94a2e 3145 rtd->close_delayed_work_func = snd_soc_close_delayed_work;
ddee627c 3146
48c7699f 3147 pcm->nonatomic = rtd->dai_link->nonatomic;
ddee627c
LG
3148 rtd->pcm = pcm;
3149 pcm->private_data = rtd;
01d7584c 3150
a342031c 3151 if (rtd->dai_link->no_pcm || rtd->dai_link->params) {
01d7584c
LG
3152 if (playback)
3153 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
3154 if (capture)
3155 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
3156 goto out;
3157 }
3158
3159 /* ASoC PCM operations */
3160 if (rtd->dai_link->dynamic) {
3161 rtd->ops.open = dpcm_fe_dai_open;
3162 rtd->ops.hw_params = dpcm_fe_dai_hw_params;
3163 rtd->ops.prepare = dpcm_fe_dai_prepare;
3164 rtd->ops.trigger = dpcm_fe_dai_trigger;
3165 rtd->ops.hw_free = dpcm_fe_dai_hw_free;
3166 rtd->ops.close = dpcm_fe_dai_close;
3167 rtd->ops.pointer = soc_pcm_pointer;
3168 } else {
3169 rtd->ops.open = soc_pcm_open;
3170 rtd->ops.hw_params = soc_pcm_hw_params;
3171 rtd->ops.prepare = soc_pcm_prepare;
3172 rtd->ops.trigger = soc_pcm_trigger;
3173 rtd->ops.hw_free = soc_pcm_hw_free;
3174 rtd->ops.close = soc_pcm_close;
3175 rtd->ops.pointer = soc_pcm_pointer;
3176 }
3177
613fb500 3178 for_each_rtd_components(rtd, i, component) {
2b544dd7 3179 const struct snd_soc_component_driver *drv = component->driver;
b8135864 3180
3b1c952c
TI
3181 if (drv->ioctl)
3182 rtd->ops.ioctl = snd_soc_pcm_component_ioctl;
1e5ddb6b
TI
3183 if (drv->sync_stop)
3184 rtd->ops.sync_stop = snd_soc_pcm_component_sync_stop;
e9067bb5 3185 if (drv->copy_user)
82d81f5c 3186 rtd->ops.copy_user = snd_soc_pcm_component_copy_user;
e9067bb5 3187 if (drv->page)
9c712e4f 3188 rtd->ops.page = snd_soc_pcm_component_page;
e9067bb5 3189 if (drv->mmap)
205875e1 3190 rtd->ops.mmap = snd_soc_pcm_component_mmap;
ddee627c
LG
3191 }
3192
3193 if (playback)
01d7584c 3194 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &rtd->ops);
ddee627c
LG
3195
3196 if (capture)
01d7584c 3197 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
ddee627c 3198
b2b2afbb 3199 ret = snd_soc_pcm_component_new(rtd);
7484291e
KM
3200 if (ret < 0) {
3201 dev_err(rtd->dev, "ASoC: pcm constructor failed: %d\n", ret);
3202 return ret;
ddee627c 3203 }
c641e5b2 3204
3d21ef0b 3205 pcm->no_device_suspend = true;
01d7584c 3206out:
2e5894d7
BC
3207 dev_info(rtd->card->dev, "%s <-> %s mapping ok\n",
3208 (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,
19bdcc7a 3209 (rtd->num_cpus > 1) ? "multicpu" : rtd->cpu_dai->name);
ddee627c
LG
3210 return ret;
3211}
01d7584c
LG
3212
3213/* is the current PCM operation for this FE ? */
3214int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream)
3215{
3216 if (fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE)
3217 return 1;
3218 return 0;
3219}
3220EXPORT_SYMBOL_GPL(snd_soc_dpcm_fe_can_update);
3221
3222/* is the current PCM operation for this BE ? */
3223int snd_soc_dpcm_be_can_update(struct snd_soc_pcm_runtime *fe,
3224 struct snd_soc_pcm_runtime *be, int stream)
3225{
3226 if ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) ||
3227 ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_BE) &&
3228 be->dpcm[stream].runtime_update))
3229 return 1;
3230 return 0;
3231}
3232EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_can_update);
3233
3234/* get the substream for this BE */
3235struct snd_pcm_substream *
3236 snd_soc_dpcm_get_substream(struct snd_soc_pcm_runtime *be, int stream)
3237{
3238 return be->pcm->streams[stream].substream;
3239}
3240EXPORT_SYMBOL_GPL(snd_soc_dpcm_get_substream);
3241
085d22be
KM
3242static int snd_soc_dpcm_check_state(struct snd_soc_pcm_runtime *fe,
3243 struct snd_soc_pcm_runtime *be,
3244 int stream,
3245 const enum snd_soc_dpcm_state *states,
3246 int num_states)
01d7584c
LG
3247{
3248 struct snd_soc_dpcm *dpcm;
3249 int state;
a9764869
KC
3250 int ret = 1;
3251 unsigned long flags;
085d22be 3252 int i;
01d7584c 3253
a9764869 3254 spin_lock_irqsave(&fe->card->dpcm_lock, flags);
d2e24d64 3255 for_each_dpcm_fe(be, stream, dpcm) {
01d7584c
LG
3256
3257 if (dpcm->fe == fe)
3258 continue;
3259
3260 state = dpcm->fe->dpcm[stream].state;
085d22be
KM
3261 for (i = 0; i < num_states; i++) {
3262 if (state == states[i]) {
3263 ret = 0;
3264 break;
3265 }
a9764869 3266 }
01d7584c 3267 }
a9764869 3268 spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
01d7584c 3269
085d22be 3270 /* it's safe to do this BE DAI */
a9764869 3271 return ret;
01d7584c 3272}
085d22be
KM
3273
3274/*
3275 * We can only hw_free, stop, pause or suspend a BE DAI if any of it's FE
3276 * are not running, paused or suspended for the specified stream direction.
3277 */
3278int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe,
3279 struct snd_soc_pcm_runtime *be, int stream)
3280{
3281 const enum snd_soc_dpcm_state state[] = {
3282 SND_SOC_DPCM_STATE_START,
3283 SND_SOC_DPCM_STATE_PAUSED,
3284 SND_SOC_DPCM_STATE_SUSPEND,
3285 };
3286
3287 return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state));
3288}
01d7584c
LG
3289EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop);
3290
3291/*
3292 * We can only change hw params a BE DAI if any of it's FE are not prepared,
3293 * running, paused or suspended for the specified stream direction.
3294 */
3295int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
3296 struct snd_soc_pcm_runtime *be, int stream)
3297{
085d22be
KM
3298 const enum snd_soc_dpcm_state state[] = {
3299 SND_SOC_DPCM_STATE_START,
3300 SND_SOC_DPCM_STATE_PAUSED,
3301 SND_SOC_DPCM_STATE_SUSPEND,
3302 SND_SOC_DPCM_STATE_PREPARE,
3303 };
01d7584c 3304
085d22be 3305 return snd_soc_dpcm_check_state(fe, be, stream, state, ARRAY_SIZE(state));
01d7584c
LG
3306}
3307EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params);