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