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