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