ASoC: dpcm: Add Dynamic PCM core operations.
[deliverable/linux.git] / sound / soc / soc-pcm.c
CommitLineData
ddee627c
LG
1/*
2 * soc-pcm.c -- ALSA SoC PCM
3 *
4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd.
6 * Copyright (C) 2010 Slimlogic Ltd.
7 * Copyright (C) 2010 Texas Instruments Inc.
8 *
9 * Authors: Liam Girdwood <lrg@ti.com>
10 * Mark Brown <broonie@opensource.wolfsonmicro.com>
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 */
18
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/delay.h>
d6652ef8 22#include <linux/pm_runtime.h>
ddee627c
LG
23#include <linux/slab.h>
24#include <linux/workqueue.h>
01d7584c 25#include <linux/export.h>
ddee627c
LG
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
01d7584c 30#include <sound/soc-dpcm.h>
ddee627c
LG
31#include <sound/initval.h>
32
01d7584c
LG
33#define DPCM_MAX_BE_USERS 8
34
35/* DPCM stream event, send event to FE and all active BEs. */
36static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
37 int event)
38{
39 struct snd_soc_dpcm *dpcm;
40
41 list_for_each_entry(dpcm, &fe->dpcm[dir].be_clients, list_be) {
42
43 struct snd_soc_pcm_runtime *be = dpcm->be;
44
45 dev_dbg(be->dev, "pm: BE %s event %d dir %d\n",
46 be->dai_link->name, event, dir);
47
48 snd_soc_dapm_stream_event(be, dir, event);
49 }
50
51 snd_soc_dapm_stream_event(fe, dir, event);
52
53 return 0;
54}
55
17841020
DA
56static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream,
57 struct snd_soc_dai *soc_dai)
ddee627c
LG
58{
59 struct snd_soc_pcm_runtime *rtd = substream->private_data;
ddee627c
LG
60 int ret;
61
17841020 62 if (!soc_dai->driver->symmetric_rates &&
ddee627c
LG
63 !rtd->dai_link->symmetric_rates)
64 return 0;
65
66 /* This can happen if multiple streams are starting simultaneously -
67 * the second can need to get its constraints before the first has
68 * picked a rate. Complain and allow the application to carry on.
69 */
17841020
DA
70 if (!soc_dai->rate) {
71 dev_warn(soc_dai->dev,
ddee627c
LG
72 "Not enforcing symmetric_rates due to race\n");
73 return 0;
74 }
75
17841020 76 dev_dbg(soc_dai->dev, "Symmetry forces %dHz rate\n", soc_dai->rate);
ddee627c
LG
77
78 ret = snd_pcm_hw_constraint_minmax(substream->runtime,
79 SNDRV_PCM_HW_PARAM_RATE,
17841020 80 soc_dai->rate, soc_dai->rate);
ddee627c 81 if (ret < 0) {
17841020 82 dev_err(soc_dai->dev,
ddee627c
LG
83 "Unable to apply rate symmetry constraint: %d\n", ret);
84 return ret;
85 }
86
87 return 0;
88}
89
58ba9b25
MB
90/*
91 * List of sample sizes that might go over the bus for parameter
92 * application. There ought to be a wildcard sample size for things
93 * like the DAC/ADC resolution to use but there isn't right now.
94 */
95static int sample_sizes[] = {
88e33954 96 24, 32,
58ba9b25
MB
97};
98
99static void soc_pcm_apply_msb(struct snd_pcm_substream *substream,
100 struct snd_soc_dai *dai)
101{
102 int ret, i, bits;
103
104 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
105 bits = dai->driver->playback.sig_bits;
106 else
107 bits = dai->driver->capture.sig_bits;
108
109 if (!bits)
110 return;
111
112 for (i = 0; i < ARRAY_SIZE(sample_sizes); i++) {
278047fd
MB
113 if (bits >= sample_sizes[i])
114 continue;
115
116 ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0,
117 sample_sizes[i], bits);
58ba9b25
MB
118 if (ret != 0)
119 dev_warn(dai->dev,
120 "Failed to set MSB %d/%d: %d\n",
121 bits, sample_sizes[i], ret);
122 }
123}
124
ddee627c
LG
125/*
126 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
127 * then initialized and any private data can be allocated. This also calls
128 * startup for the cpu DAI, platform, machine and codec DAI.
129 */
130static int soc_pcm_open(struct snd_pcm_substream *substream)
131{
132 struct snd_soc_pcm_runtime *rtd = substream->private_data;
133 struct snd_pcm_runtime *runtime = substream->runtime;
134 struct snd_soc_platform *platform = rtd->platform;
135 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
136 struct snd_soc_dai *codec_dai = rtd->codec_dai;
137 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
138 struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver;
139 int ret = 0;
140
d6652ef8
MB
141 pm_runtime_get_sync(cpu_dai->dev);
142 pm_runtime_get_sync(codec_dai->dev);
143 pm_runtime_get_sync(platform->dev);
144
b8c0dab9 145 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
ddee627c
LG
146
147 /* startup the audio subsystem */
148 if (cpu_dai->driver->ops->startup) {
149 ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
150 if (ret < 0) {
25bfe662
MB
151 dev_err(cpu_dai->dev, "can't open interface %s: %d\n",
152 cpu_dai->name, ret);
ddee627c
LG
153 goto out;
154 }
155 }
156
157 if (platform->driver->ops && platform->driver->ops->open) {
158 ret = platform->driver->ops->open(substream);
159 if (ret < 0) {
25bfe662
MB
160 dev_err(platform->dev, "can't open platform %s: %d\n",
161 platform->name, ret);
ddee627c
LG
162 goto platform_err;
163 }
164 }
165
166 if (codec_dai->driver->ops->startup) {
167 ret = codec_dai->driver->ops->startup(substream, codec_dai);
168 if (ret < 0) {
25bfe662
MB
169 dev_err(codec_dai->dev, "can't open codec %s: %d\n",
170 codec_dai->name, ret);
ddee627c
LG
171 goto codec_dai_err;
172 }
173 }
174
175 if (rtd->dai_link->ops && rtd->dai_link->ops->startup) {
176 ret = rtd->dai_link->ops->startup(substream);
177 if (ret < 0) {
25bfe662
MB
178 pr_err("asoc: %s startup failed: %d\n",
179 rtd->dai_link->name, ret);
ddee627c
LG
180 goto machine_err;
181 }
182 }
183
01d7584c
LG
184 /* Dynamic PCM DAI links compat checks use dynamic capabilities */
185 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm)
186 goto dynamic;
187
ddee627c
LG
188 /* Check that the codec and cpu DAIs are compatible */
189 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
190 runtime->hw.rate_min =
191 max(codec_dai_drv->playback.rate_min,
192 cpu_dai_drv->playback.rate_min);
193 runtime->hw.rate_max =
194 min(codec_dai_drv->playback.rate_max,
195 cpu_dai_drv->playback.rate_max);
196 runtime->hw.channels_min =
197 max(codec_dai_drv->playback.channels_min,
198 cpu_dai_drv->playback.channels_min);
199 runtime->hw.channels_max =
200 min(codec_dai_drv->playback.channels_max,
201 cpu_dai_drv->playback.channels_max);
202 runtime->hw.formats =
203 codec_dai_drv->playback.formats & cpu_dai_drv->playback.formats;
204 runtime->hw.rates =
205 codec_dai_drv->playback.rates & cpu_dai_drv->playback.rates;
206 if (codec_dai_drv->playback.rates
207 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
208 runtime->hw.rates |= cpu_dai_drv->playback.rates;
209 if (cpu_dai_drv->playback.rates
210 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
211 runtime->hw.rates |= codec_dai_drv->playback.rates;
212 } else {
213 runtime->hw.rate_min =
214 max(codec_dai_drv->capture.rate_min,
215 cpu_dai_drv->capture.rate_min);
216 runtime->hw.rate_max =
217 min(codec_dai_drv->capture.rate_max,
218 cpu_dai_drv->capture.rate_max);
219 runtime->hw.channels_min =
220 max(codec_dai_drv->capture.channels_min,
221 cpu_dai_drv->capture.channels_min);
222 runtime->hw.channels_max =
223 min(codec_dai_drv->capture.channels_max,
224 cpu_dai_drv->capture.channels_max);
225 runtime->hw.formats =
226 codec_dai_drv->capture.formats & cpu_dai_drv->capture.formats;
227 runtime->hw.rates =
228 codec_dai_drv->capture.rates & cpu_dai_drv->capture.rates;
229 if (codec_dai_drv->capture.rates
230 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
231 runtime->hw.rates |= cpu_dai_drv->capture.rates;
232 if (cpu_dai_drv->capture.rates
233 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
234 runtime->hw.rates |= codec_dai_drv->capture.rates;
235 }
236
237 ret = -EINVAL;
238 snd_pcm_limit_hw_rates(runtime);
239 if (!runtime->hw.rates) {
240 printk(KERN_ERR "asoc: %s <-> %s No matching rates\n",
241 codec_dai->name, cpu_dai->name);
242 goto config_err;
243 }
244 if (!runtime->hw.formats) {
245 printk(KERN_ERR "asoc: %s <-> %s No matching formats\n",
246 codec_dai->name, cpu_dai->name);
247 goto config_err;
248 }
249 if (!runtime->hw.channels_min || !runtime->hw.channels_max ||
250 runtime->hw.channels_min > runtime->hw.channels_max) {
251 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
252 codec_dai->name, cpu_dai->name);
253 goto config_err;
254 }
255
58ba9b25
MB
256 soc_pcm_apply_msb(substream, codec_dai);
257 soc_pcm_apply_msb(substream, cpu_dai);
258
ddee627c 259 /* Symmetry only applies if we've already got an active stream. */
17841020
DA
260 if (cpu_dai->active) {
261 ret = soc_pcm_apply_symmetry(substream, cpu_dai);
262 if (ret != 0)
263 goto config_err;
264 }
265
266 if (codec_dai->active) {
267 ret = soc_pcm_apply_symmetry(substream, codec_dai);
ddee627c
LG
268 if (ret != 0)
269 goto config_err;
270 }
271
272 pr_debug("asoc: %s <-> %s info:\n",
273 codec_dai->name, cpu_dai->name);
274 pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
275 pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
276 runtime->hw.channels_max);
277 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
278 runtime->hw.rate_max);
279
01d7584c 280dynamic:
ddee627c
LG
281 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
282 cpu_dai->playback_active++;
283 codec_dai->playback_active++;
284 } else {
285 cpu_dai->capture_active++;
286 codec_dai->capture_active++;
287 }
288 cpu_dai->active++;
289 codec_dai->active++;
290 rtd->codec->active++;
b8c0dab9 291 mutex_unlock(&rtd->pcm_mutex);
ddee627c
LG
292 return 0;
293
294config_err:
295 if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
296 rtd->dai_link->ops->shutdown(substream);
297
298machine_err:
299 if (codec_dai->driver->ops->shutdown)
300 codec_dai->driver->ops->shutdown(substream, codec_dai);
301
302codec_dai_err:
303 if (platform->driver->ops && platform->driver->ops->close)
304 platform->driver->ops->close(substream);
305
306platform_err:
307 if (cpu_dai->driver->ops->shutdown)
308 cpu_dai->driver->ops->shutdown(substream, cpu_dai);
309out:
b8c0dab9 310 mutex_unlock(&rtd->pcm_mutex);
d6652ef8
MB
311
312 pm_runtime_put(platform->dev);
313 pm_runtime_put(codec_dai->dev);
314 pm_runtime_put(cpu_dai->dev);
315
ddee627c
LG
316 return ret;
317}
318
319/*
320 * Power down the audio subsystem pmdown_time msecs after close is called.
321 * This is to ensure there are no pops or clicks in between any music tracks
322 * due to DAPM power cycling.
323 */
324static void close_delayed_work(struct work_struct *work)
325{
326 struct snd_soc_pcm_runtime *rtd =
327 container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
328 struct snd_soc_dai *codec_dai = rtd->codec_dai;
329
b8c0dab9 330 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
ddee627c
LG
331
332 pr_debug("pop wq checking: %s status: %s waiting: %s\n",
333 codec_dai->driver->playback.stream_name,
334 codec_dai->playback_active ? "active" : "inactive",
335 codec_dai->pop_wait ? "yes" : "no");
336
337 /* are we waiting on this codec DAI stream */
338 if (codec_dai->pop_wait == 1) {
339 codec_dai->pop_wait = 0;
7bd3a6f3 340 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
d9b0951b 341 SND_SOC_DAPM_STREAM_STOP);
ddee627c
LG
342 }
343
b8c0dab9 344 mutex_unlock(&rtd->pcm_mutex);
ddee627c
LG
345}
346
347/*
348 * Called by ALSA when a PCM substream is closed. Private data can be
349 * freed here. The cpu DAI, codec DAI, machine and platform are also
350 * shutdown.
351 */
91d5e6b4 352static int soc_pcm_close(struct snd_pcm_substream *substream)
ddee627c
LG
353{
354 struct snd_soc_pcm_runtime *rtd = substream->private_data;
355 struct snd_soc_platform *platform = rtd->platform;
356 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
357 struct snd_soc_dai *codec_dai = rtd->codec_dai;
358 struct snd_soc_codec *codec = rtd->codec;
359
b8c0dab9 360 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
ddee627c
LG
361
362 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
363 cpu_dai->playback_active--;
364 codec_dai->playback_active--;
365 } else {
366 cpu_dai->capture_active--;
367 codec_dai->capture_active--;
368 }
369
370 cpu_dai->active--;
371 codec_dai->active--;
372 codec->active--;
373
17841020
DA
374 /* clear the corresponding DAIs rate when inactive */
375 if (!cpu_dai->active)
376 cpu_dai->rate = 0;
377
378 if (!codec_dai->active)
379 codec_dai->rate = 0;
25b76791 380
ddee627c
LG
381 /* Muting the DAC suppresses artifacts caused during digital
382 * shutdown, for example from stopping clocks.
383 */
384 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
385 snd_soc_dai_digital_mute(codec_dai, 1);
386
387 if (cpu_dai->driver->ops->shutdown)
388 cpu_dai->driver->ops->shutdown(substream, cpu_dai);
389
390 if (codec_dai->driver->ops->shutdown)
391 codec_dai->driver->ops->shutdown(substream, codec_dai);
392
393 if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
394 rtd->dai_link->ops->shutdown(substream);
395
396 if (platform->driver->ops && platform->driver->ops->close)
397 platform->driver->ops->close(substream);
398 cpu_dai->runtime = NULL;
399
400 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
b5d1d036 401 if (!rtd->pmdown_time || codec->ignore_pmdown_time ||
5b6247ab 402 rtd->dai_link->ignore_pmdown_time) {
1d69c5c5
PU
403 /* powered down playback stream now */
404 snd_soc_dapm_stream_event(rtd,
7bd3a6f3 405 SNDRV_PCM_STREAM_PLAYBACK,
7bd3a6f3 406 SND_SOC_DAPM_STREAM_STOP);
1d69c5c5
PU
407 } else {
408 /* start delayed pop wq here for playback streams */
409 codec_dai->pop_wait = 1;
410 schedule_delayed_work(&rtd->delayed_work,
411 msecs_to_jiffies(rtd->pmdown_time));
412 }
ddee627c
LG
413 } else {
414 /* capture streams can be powered down now */
7bd3a6f3 415 snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE,
d9b0951b 416 SND_SOC_DAPM_STREAM_STOP);
ddee627c
LG
417 }
418
b8c0dab9 419 mutex_unlock(&rtd->pcm_mutex);
d6652ef8
MB
420
421 pm_runtime_put(platform->dev);
422 pm_runtime_put(codec_dai->dev);
423 pm_runtime_put(cpu_dai->dev);
424
ddee627c
LG
425 return 0;
426}
427
428/*
429 * Called by ALSA when the PCM substream is prepared, can set format, sample
430 * rate, etc. This function is non atomic and can be called multiple times,
431 * it can refer to the runtime info.
432 */
433static int soc_pcm_prepare(struct snd_pcm_substream *substream)
434{
435 struct snd_soc_pcm_runtime *rtd = substream->private_data;
436 struct snd_soc_platform *platform = rtd->platform;
437 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
438 struct snd_soc_dai *codec_dai = rtd->codec_dai;
439 int ret = 0;
440
b8c0dab9 441 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
ddee627c
LG
442
443 if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) {
444 ret = rtd->dai_link->ops->prepare(substream);
445 if (ret < 0) {
25bfe662 446 pr_err("asoc: machine prepare error: %d\n", ret);
ddee627c
LG
447 goto out;
448 }
449 }
450
451 if (platform->driver->ops && platform->driver->ops->prepare) {
452 ret = platform->driver->ops->prepare(substream);
453 if (ret < 0) {
25bfe662
MB
454 dev_err(platform->dev, "platform prepare error: %d\n",
455 ret);
ddee627c
LG
456 goto out;
457 }
458 }
459
460 if (codec_dai->driver->ops->prepare) {
461 ret = codec_dai->driver->ops->prepare(substream, codec_dai);
462 if (ret < 0) {
25bfe662
MB
463 dev_err(codec_dai->dev, "DAI prepare error: %d\n",
464 ret);
ddee627c
LG
465 goto out;
466 }
467 }
468
469 if (cpu_dai->driver->ops->prepare) {
470 ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
471 if (ret < 0) {
25bfe662
MB
472 dev_err(cpu_dai->dev, "DAI prepare error: %d\n",
473 ret);
ddee627c
LG
474 goto out;
475 }
476 }
477
478 /* cancel any delayed stream shutdown that is pending */
479 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
480 codec_dai->pop_wait) {
481 codec_dai->pop_wait = 0;
482 cancel_delayed_work(&rtd->delayed_work);
483 }
484
d9b0951b
LG
485 snd_soc_dapm_stream_event(rtd, substream->stream,
486 SND_SOC_DAPM_STREAM_START);
ddee627c
LG
487
488 snd_soc_dai_digital_mute(codec_dai, 0);
489
490out:
b8c0dab9 491 mutex_unlock(&rtd->pcm_mutex);
ddee627c
LG
492 return ret;
493}
494
495/*
496 * Called by ALSA when the hardware params are set by application. This
497 * function can also be called multiple times and can allocate buffers
498 * (using snd_pcm_lib_* ). It's non-atomic.
499 */
500static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
501 struct snd_pcm_hw_params *params)
502{
503 struct snd_soc_pcm_runtime *rtd = substream->private_data;
504 struct snd_soc_platform *platform = rtd->platform;
505 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
506 struct snd_soc_dai *codec_dai = rtd->codec_dai;
507 int ret = 0;
508
b8c0dab9 509 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
ddee627c
LG
510
511 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) {
512 ret = rtd->dai_link->ops->hw_params(substream, params);
513 if (ret < 0) {
25bfe662 514 pr_err("asoc: machine hw_params failed: %d\n", ret);
ddee627c
LG
515 goto out;
516 }
517 }
518
519 if (codec_dai->driver->ops->hw_params) {
520 ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai);
521 if (ret < 0) {
25bfe662
MB
522 dev_err(codec_dai->dev, "can't set %s hw params: %d\n",
523 codec_dai->name, ret);
ddee627c
LG
524 goto codec_err;
525 }
526 }
527
528 if (cpu_dai->driver->ops->hw_params) {
529 ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai);
530 if (ret < 0) {
25bfe662
MB
531 dev_err(cpu_dai->dev, "%s hw params failed: %d\n",
532 cpu_dai->name, ret);
ddee627c
LG
533 goto interface_err;
534 }
535 }
536
537 if (platform->driver->ops && platform->driver->ops->hw_params) {
538 ret = platform->driver->ops->hw_params(substream, params);
539 if (ret < 0) {
25bfe662
MB
540 dev_err(platform->dev, "%s hw params failed: %d\n",
541 platform->name, ret);
ddee627c
LG
542 goto platform_err;
543 }
544 }
545
17841020
DA
546 /* store the rate for each DAIs */
547 cpu_dai->rate = params_rate(params);
548 codec_dai->rate = params_rate(params);
ddee627c
LG
549
550out:
b8c0dab9 551 mutex_unlock(&rtd->pcm_mutex);
ddee627c
LG
552 return ret;
553
554platform_err:
555 if (cpu_dai->driver->ops->hw_free)
556 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
557
558interface_err:
559 if (codec_dai->driver->ops->hw_free)
560 codec_dai->driver->ops->hw_free(substream, codec_dai);
561
562codec_err:
563 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
564 rtd->dai_link->ops->hw_free(substream);
565
b8c0dab9 566 mutex_unlock(&rtd->pcm_mutex);
ddee627c
LG
567 return ret;
568}
569
570/*
571 * Frees resources allocated by hw_params, can be called multiple times
572 */
573static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
574{
575 struct snd_soc_pcm_runtime *rtd = substream->private_data;
576 struct snd_soc_platform *platform = rtd->platform;
577 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
578 struct snd_soc_dai *codec_dai = rtd->codec_dai;
579 struct snd_soc_codec *codec = rtd->codec;
580
b8c0dab9 581 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
ddee627c
LG
582
583 /* apply codec digital mute */
584 if (!codec->active)
585 snd_soc_dai_digital_mute(codec_dai, 1);
586
587 /* free any machine hw params */
588 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
589 rtd->dai_link->ops->hw_free(substream);
590
591 /* free any DMA resources */
592 if (platform->driver->ops && platform->driver->ops->hw_free)
593 platform->driver->ops->hw_free(substream);
594
595 /* now free hw params for the DAIs */
596 if (codec_dai->driver->ops->hw_free)
597 codec_dai->driver->ops->hw_free(substream, codec_dai);
598
599 if (cpu_dai->driver->ops->hw_free)
600 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
601
b8c0dab9 602 mutex_unlock(&rtd->pcm_mutex);
ddee627c
LG
603 return 0;
604}
605
606static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
607{
608 struct snd_soc_pcm_runtime *rtd = substream->private_data;
609 struct snd_soc_platform *platform = rtd->platform;
610 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
611 struct snd_soc_dai *codec_dai = rtd->codec_dai;
612 int ret;
613
614 if (codec_dai->driver->ops->trigger) {
615 ret = codec_dai->driver->ops->trigger(substream, cmd, codec_dai);
616 if (ret < 0)
617 return ret;
618 }
619
620 if (platform->driver->ops && platform->driver->ops->trigger) {
621 ret = platform->driver->ops->trigger(substream, cmd);
622 if (ret < 0)
623 return ret;
624 }
625
626 if (cpu_dai->driver->ops->trigger) {
627 ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai);
628 if (ret < 0)
629 return ret;
630 }
631 return 0;
632}
633
634/*
635 * soc level wrapper for pointer callback
636 * If cpu_dai, codec_dai, platform driver has the delay callback, than
637 * the runtime->delay will be updated accordingly.
638 */
639static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
640{
641 struct snd_soc_pcm_runtime *rtd = substream->private_data;
642 struct snd_soc_platform *platform = rtd->platform;
643 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
644 struct snd_soc_dai *codec_dai = rtd->codec_dai;
645 struct snd_pcm_runtime *runtime = substream->runtime;
646 snd_pcm_uframes_t offset = 0;
647 snd_pcm_sframes_t delay = 0;
648
649 if (platform->driver->ops && platform->driver->ops->pointer)
650 offset = platform->driver->ops->pointer(substream);
651
652 if (cpu_dai->driver->ops->delay)
653 delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
654
655 if (codec_dai->driver->ops->delay)
656 delay += codec_dai->driver->ops->delay(substream, codec_dai);
657
658 if (platform->driver->delay)
659 delay += platform->driver->delay(substream, codec_dai);
660
661 runtime->delay = delay;
662
663 return offset;
664}
665
01d7584c
LG
666/* connect a FE and BE */
667static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
668 struct snd_soc_pcm_runtime *be, int stream)
669{
670 struct snd_soc_dpcm *dpcm;
671
672 /* only add new dpcms */
673 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
674 if (dpcm->be == be && dpcm->fe == fe)
675 return 0;
676 }
677
678 dpcm = kzalloc(sizeof(struct snd_soc_dpcm), GFP_KERNEL);
679 if (!dpcm)
680 return -ENOMEM;
681
682 dpcm->be = be;
683 dpcm->fe = fe;
684 be->dpcm[stream].runtime = fe->dpcm[stream].runtime;
685 dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW;
686 list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients);
687 list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients);
688
689 dev_dbg(fe->dev, " connected new DPCM %s path %s %s %s\n",
690 stream ? "capture" : "playback", fe->dai_link->name,
691 stream ? "<-" : "->", be->dai_link->name);
692
693 return 1;
694}
695
696/* reparent a BE onto another FE */
697static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
698 struct snd_soc_pcm_runtime *be, int stream)
699{
700 struct snd_soc_dpcm *dpcm;
701 struct snd_pcm_substream *fe_substream, *be_substream;
702
703 /* reparent if BE is connected to other FEs */
704 if (!be->dpcm[stream].users)
705 return;
706
707 be_substream = snd_soc_dpcm_get_substream(be, stream);
708
709 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
710 if (dpcm->fe == fe)
711 continue;
712
713 dev_dbg(fe->dev, " reparent %s path %s %s %s\n",
714 stream ? "capture" : "playback",
715 dpcm->fe->dai_link->name,
716 stream ? "<-" : "->", dpcm->be->dai_link->name);
717
718 fe_substream = snd_soc_dpcm_get_substream(dpcm->fe, stream);
719 be_substream->runtime = fe_substream->runtime;
720 break;
721 }
722}
723
724/* disconnect a BE and FE */
725static void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
726{
727 struct snd_soc_dpcm *dpcm, *d;
728
729 list_for_each_entry_safe(dpcm, d, &fe->dpcm[stream].be_clients, list_be) {
730 dev_dbg(fe->dev, "BE %s disconnect check for %s\n",
731 stream ? "capture" : "playback",
732 dpcm->be->dai_link->name);
733
734 if (dpcm->state != SND_SOC_DPCM_LINK_STATE_FREE)
735 continue;
736
737 dev_dbg(fe->dev, " freed DSP %s path %s %s %s\n",
738 stream ? "capture" : "playback", fe->dai_link->name,
739 stream ? "<-" : "->", dpcm->be->dai_link->name);
740
741 /* BEs still alive need new FE */
742 dpcm_be_reparent(fe, dpcm->be, stream);
743
744 list_del(&dpcm->list_be);
745 list_del(&dpcm->list_fe);
746 kfree(dpcm);
747 }
748}
749
750/* get BE for DAI widget and stream */
751static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
752 struct snd_soc_dapm_widget *widget, int stream)
753{
754 struct snd_soc_pcm_runtime *be;
755 int i;
756
757 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
758 for (i = 0; i < card->num_links; i++) {
759 be = &card->rtd[i];
760
761 if (be->cpu_dai->playback_widget == widget ||
762 be->codec_dai->playback_widget == widget)
763 return be;
764 }
765 } else {
766
767 for (i = 0; i < card->num_links; i++) {
768 be = &card->rtd[i];
769
770 if (be->cpu_dai->capture_widget == widget ||
771 be->codec_dai->capture_widget == widget)
772 return be;
773 }
774 }
775
776 dev_err(card->dev, "can't get %s BE for %s\n",
777 stream ? "capture" : "playback", widget->name);
778 return NULL;
779}
780
781static inline struct snd_soc_dapm_widget *
782 rtd_get_cpu_widget(struct snd_soc_pcm_runtime *rtd, int stream)
783{
784 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
785 return rtd->cpu_dai->playback_widget;
786 else
787 return rtd->cpu_dai->capture_widget;
788}
789
790static inline struct snd_soc_dapm_widget *
791 rtd_get_codec_widget(struct snd_soc_pcm_runtime *rtd, int stream)
792{
793 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
794 return rtd->codec_dai->playback_widget;
795 else
796 return rtd->codec_dai->capture_widget;
797}
798
799static int widget_in_list(struct snd_soc_dapm_widget_list *list,
800 struct snd_soc_dapm_widget *widget)
801{
802 int i;
803
804 for (i = 0; i < list->num_widgets; i++) {
805 if (widget == list->widgets[i])
806 return 1;
807 }
808
809 return 0;
810}
811
812static int dpcm_path_get(struct snd_soc_pcm_runtime *fe,
813 int stream, struct snd_soc_dapm_widget_list **list_)
814{
815 struct snd_soc_dai *cpu_dai = fe->cpu_dai;
816 struct snd_soc_dapm_widget_list *list;
817 int paths;
818
819 list = kzalloc(sizeof(struct snd_soc_dapm_widget_list) +
820 sizeof(struct snd_soc_dapm_widget *), GFP_KERNEL);
821 if (list == NULL)
822 return -ENOMEM;
823
824 /* get number of valid DAI paths and their widgets */
825 paths = snd_soc_dapm_dai_get_connected_widgets(cpu_dai, stream, &list);
826
827 dev_dbg(fe->dev, "found %d audio %s paths\n", paths,
828 stream ? "capture" : "playback");
829
830 *list_ = list;
831 return paths;
832}
833
834static inline void dpcm_path_put(struct snd_soc_dapm_widget_list **list)
835{
836 kfree(*list);
837}
838
839static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
840 struct snd_soc_dapm_widget_list **list_)
841{
842 struct snd_soc_dpcm *dpcm;
843 struct snd_soc_dapm_widget_list *list = *list_;
844 struct snd_soc_dapm_widget *widget;
845 int prune = 0;
846
847 /* Destroy any old FE <--> BE connections */
848 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
849
850 /* is there a valid CPU DAI widget for this BE */
851 widget = rtd_get_cpu_widget(dpcm->be, stream);
852
853 /* prune the BE if it's no longer in our active list */
854 if (widget && widget_in_list(list, widget))
855 continue;
856
857 /* is there a valid CODEC DAI widget for this BE */
858 widget = rtd_get_codec_widget(dpcm->be, stream);
859
860 /* prune the BE if it's no longer in our active list */
861 if (widget && widget_in_list(list, widget))
862 continue;
863
864 dev_dbg(fe->dev, "pruning %s BE %s for %s\n",
865 stream ? "capture" : "playback",
866 dpcm->be->dai_link->name, fe->dai_link->name);
867 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
868 dpcm->be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
869 prune++;
870 }
871
872 dev_dbg(fe->dev, "found %d old BE paths for pruning\n", prune);
873 return prune;
874}
875
876static int dpcm_add_paths(struct snd_soc_pcm_runtime *fe, int stream,
877 struct snd_soc_dapm_widget_list **list_)
878{
879 struct snd_soc_card *card = fe->card;
880 struct snd_soc_dapm_widget_list *list = *list_;
881 struct snd_soc_pcm_runtime *be;
882 int i, new = 0, err;
883
884 /* Create any new FE <--> BE connections */
885 for (i = 0; i < list->num_widgets; i++) {
886
887 if (list->widgets[i]->id != snd_soc_dapm_dai)
888 continue;
889
890 /* is there a valid BE rtd for this widget */
891 be = dpcm_get_be(card, list->widgets[i], stream);
892 if (!be) {
893 dev_err(fe->dev, "no BE found for %s\n",
894 list->widgets[i]->name);
895 continue;
896 }
897
898 /* make sure BE is a real BE */
899 if (!be->dai_link->no_pcm)
900 continue;
901
902 /* don't connect if FE is not running */
903 if (!fe->dpcm[stream].runtime)
904 continue;
905
906 /* newly connected FE and BE */
907 err = dpcm_be_connect(fe, be, stream);
908 if (err < 0) {
909 dev_err(fe->dev, "can't connect %s\n",
910 list->widgets[i]->name);
911 break;
912 } else if (err == 0) /* already connected */
913 continue;
914
915 /* new */
916 be->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_BE;
917 new++;
918 }
919
920 dev_dbg(fe->dev, "found %d new BE paths\n", new);
921 return new;
922}
923
924/*
925 * Find the corresponding BE DAIs that source or sink audio to this
926 * FE substream.
927 */
928static int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
929 int stream, struct snd_soc_dapm_widget_list **list, int new)
930{
931 if (new)
932 return dpcm_add_paths(fe, stream, list);
933 else
934 return dpcm_prune_paths(fe, stream, list);
935}
936
937static void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream)
938{
939 struct snd_soc_dpcm *dpcm;
940
941 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
942 dpcm->be->dpcm[stream].runtime_update =
943 SND_SOC_DPCM_UPDATE_NO;
944}
945
946static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe,
947 int stream)
948{
949 struct snd_soc_dpcm *dpcm;
950
951 /* disable any enabled and non active backends */
952 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
953
954 struct snd_soc_pcm_runtime *be = dpcm->be;
955 struct snd_pcm_substream *be_substream =
956 snd_soc_dpcm_get_substream(be, stream);
957
958 if (be->dpcm[stream].users == 0)
959 dev_err(be->dev, "no users %s at close - state %d\n",
960 stream ? "capture" : "playback",
961 be->dpcm[stream].state);
962
963 if (--be->dpcm[stream].users != 0)
964 continue;
965
966 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)
967 continue;
968
969 soc_pcm_close(be_substream);
970 be_substream->runtime = NULL;
971 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
972 }
973}
974
975static int dpcm_be_dai_startup(struct snd_soc_pcm_runtime *fe, int stream)
976{
977 struct snd_soc_dpcm *dpcm;
978 int err, count = 0;
979
980 /* only startup BE DAIs that are either sinks or sources to this FE DAI */
981 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
982
983 struct snd_soc_pcm_runtime *be = dpcm->be;
984 struct snd_pcm_substream *be_substream =
985 snd_soc_dpcm_get_substream(be, stream);
986
987 /* is this op for this BE ? */
988 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
989 continue;
990
991 /* first time the dpcm is open ? */
992 if (be->dpcm[stream].users == DPCM_MAX_BE_USERS)
993 dev_err(be->dev, "too many users %s at open %d\n",
994 stream ? "capture" : "playback",
995 be->dpcm[stream].state);
996
997 if (be->dpcm[stream].users++ != 0)
998 continue;
999
1000 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_NEW) &&
1001 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_CLOSE))
1002 continue;
1003
1004 dev_dbg(be->dev, "dpcm: open BE %s\n", be->dai_link->name);
1005
1006 be_substream->runtime = be->dpcm[stream].runtime;
1007 err = soc_pcm_open(be_substream);
1008 if (err < 0) {
1009 dev_err(be->dev, "BE open failed %d\n", err);
1010 be->dpcm[stream].users--;
1011 if (be->dpcm[stream].users < 0)
1012 dev_err(be->dev, "no users %s at unwind %d\n",
1013 stream ? "capture" : "playback",
1014 be->dpcm[stream].state);
1015
1016 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1017 goto unwind;
1018 }
1019
1020 be->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
1021 count++;
1022 }
1023
1024 return count;
1025
1026unwind:
1027 /* disable any enabled and non active backends */
1028 list_for_each_entry_continue_reverse(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1029 struct snd_soc_pcm_runtime *be = dpcm->be;
1030 struct snd_pcm_substream *be_substream =
1031 snd_soc_dpcm_get_substream(be, stream);
1032
1033 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1034 continue;
1035
1036 if (be->dpcm[stream].users == 0)
1037 dev_err(be->dev, "no users %s at close %d\n",
1038 stream ? "capture" : "playback",
1039 be->dpcm[stream].state);
1040
1041 if (--be->dpcm[stream].users != 0)
1042 continue;
1043
1044 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)
1045 continue;
1046
1047 soc_pcm_close(be_substream);
1048 be_substream->runtime = NULL;
1049 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1050 }
1051
1052 return err;
1053}
1054
1055void dpcm_set_fe_runtime(struct snd_pcm_substream *substream)
1056{
1057 struct snd_pcm_runtime *runtime = substream->runtime;
1058 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1059 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1060 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
1061
1062 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1063 runtime->hw.rate_min = cpu_dai_drv->playback.rate_min;
1064 runtime->hw.rate_max = cpu_dai_drv->playback.rate_max;
1065 runtime->hw.channels_min = cpu_dai_drv->playback.channels_min;
1066 runtime->hw.channels_max = cpu_dai_drv->playback.channels_max;
1067 runtime->hw.formats &= cpu_dai_drv->playback.formats;
1068 runtime->hw.rates = cpu_dai_drv->playback.rates;
1069 } else {
1070 runtime->hw.rate_min = cpu_dai_drv->capture.rate_min;
1071 runtime->hw.rate_max = cpu_dai_drv->capture.rate_max;
1072 runtime->hw.channels_min = cpu_dai_drv->capture.channels_min;
1073 runtime->hw.channels_max = cpu_dai_drv->capture.channels_max;
1074 runtime->hw.formats &= cpu_dai_drv->capture.formats;
1075 runtime->hw.rates = cpu_dai_drv->capture.rates;
1076 }
1077}
1078
1079static int dpcm_fe_dai_startup(struct snd_pcm_substream *fe_substream)
1080{
1081 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1082 struct snd_pcm_runtime *runtime = fe_substream->runtime;
1083 int stream = fe_substream->stream, ret = 0;
1084
1085 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1086
1087 ret = dpcm_be_dai_startup(fe, fe_substream->stream);
1088 if (ret < 0) {
1089 dev_err(fe->dev,"dpcm: failed to start some BEs %d\n", ret);
1090 goto be_err;
1091 }
1092
1093 dev_dbg(fe->dev, "dpcm: open FE %s\n", fe->dai_link->name);
1094
1095 /* start the DAI frontend */
1096 ret = soc_pcm_open(fe_substream);
1097 if (ret < 0) {
1098 dev_err(fe->dev,"dpcm: failed to start FE %d\n", ret);
1099 goto unwind;
1100 }
1101
1102 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_OPEN;
1103
1104 dpcm_set_fe_runtime(fe_substream);
1105 snd_pcm_limit_hw_rates(runtime);
1106
1107 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1108 return 0;
1109
1110unwind:
1111 dpcm_be_dai_startup_unwind(fe, fe_substream->stream);
1112be_err:
1113 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1114 return ret;
1115}
1116
1117static int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
1118{
1119 struct snd_soc_dpcm *dpcm;
1120
1121 /* only shutdown BEs that are either sinks or sources to this FE DAI */
1122 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1123
1124 struct snd_soc_pcm_runtime *be = dpcm->be;
1125 struct snd_pcm_substream *be_substream =
1126 snd_soc_dpcm_get_substream(be, stream);
1127
1128 /* is this op for this BE ? */
1129 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1130 continue;
1131
1132 if (be->dpcm[stream].users == 0)
1133 dev_err(be->dev, "no users %s at close - state %d\n",
1134 stream ? "capture" : "playback",
1135 be->dpcm[stream].state);
1136
1137 if (--be->dpcm[stream].users != 0)
1138 continue;
1139
1140 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1141 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN))
1142 continue;
1143
1144 dev_dbg(be->dev, "dpcm: close BE %s\n",
1145 dpcm->fe->dai_link->name);
1146
1147 soc_pcm_close(be_substream);
1148 be_substream->runtime = NULL;
1149
1150 be->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1151 }
1152 return 0;
1153}
1154
1155static int dpcm_fe_dai_shutdown(struct snd_pcm_substream *substream)
1156{
1157 struct snd_soc_pcm_runtime *fe = substream->private_data;
1158 int stream = substream->stream;
1159
1160 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1161
1162 /* shutdown the BEs */
1163 dpcm_be_dai_shutdown(fe, substream->stream);
1164
1165 dev_dbg(fe->dev, "dpcm: close FE %s\n", fe->dai_link->name);
1166
1167 /* now shutdown the frontend */
1168 soc_pcm_close(substream);
1169
1170 /* run the stream event for each BE */
1171 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_STOP);
1172
1173 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_CLOSE;
1174 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1175 return 0;
1176}
1177
1178static int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream)
1179{
1180 struct snd_soc_dpcm *dpcm;
1181
1182 /* only hw_params backends that are either sinks or sources
1183 * to this frontend DAI */
1184 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1185
1186 struct snd_soc_pcm_runtime *be = dpcm->be;
1187 struct snd_pcm_substream *be_substream =
1188 snd_soc_dpcm_get_substream(be, stream);
1189
1190 /* is this op for this BE ? */
1191 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1192 continue;
1193
1194 /* only free hw when no longer used - check all FEs */
1195 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1196 continue;
1197
1198 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1199 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
1200 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1201 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1202 continue;
1203
1204 dev_dbg(be->dev, "dpcm: hw_free BE %s\n",
1205 dpcm->fe->dai_link->name);
1206
1207 soc_pcm_hw_free(be_substream);
1208
1209 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
1210 }
1211
1212 return 0;
1213}
1214
1215int dpcm_fe_dai_hw_free(struct snd_pcm_substream *substream)
1216{
1217 struct snd_soc_pcm_runtime *fe = substream->private_data;
1218 int err, stream = substream->stream;
1219
1220 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1221 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1222
1223 dev_dbg(fe->dev, "dpcm: hw_free FE %s\n", fe->dai_link->name);
1224
1225 /* call hw_free on the frontend */
1226 err = soc_pcm_hw_free(substream);
1227 if (err < 0)
1228 dev_err(fe->dev,"dpcm: hw_free FE %s failed\n",
1229 fe->dai_link->name);
1230
1231 /* only hw_params backends that are either sinks or sources
1232 * to this frontend DAI */
1233 err = dpcm_be_dai_hw_free(fe, stream);
1234
1235 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
1236 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1237
1238 mutex_unlock(&fe->card->mutex);
1239 return 0;
1240}
1241
1242static int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream)
1243{
1244 struct snd_soc_dpcm *dpcm;
1245 int ret;
1246
1247 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1248
1249 struct snd_soc_pcm_runtime *be = dpcm->be;
1250 struct snd_pcm_substream *be_substream =
1251 snd_soc_dpcm_get_substream(be, stream);
1252
1253 /* is this op for this BE ? */
1254 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1255 continue;
1256
1257 /* only allow hw_params() if no connected FEs are running */
1258 if (!snd_soc_dpcm_can_be_params(fe, be, stream))
1259 continue;
1260
1261 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
1262 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1263 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE))
1264 continue;
1265
1266 dev_dbg(be->dev, "dpcm: hw_params BE %s\n",
1267 dpcm->fe->dai_link->name);
1268
1269 /* copy params for each dpcm */
1270 memcpy(&dpcm->hw_params, &fe->dpcm[stream].hw_params,
1271 sizeof(struct snd_pcm_hw_params));
1272
1273 /* perform any hw_params fixups */
1274 if (be->dai_link->be_hw_params_fixup) {
1275 ret = be->dai_link->be_hw_params_fixup(be,
1276 &dpcm->hw_params);
1277 if (ret < 0) {
1278 dev_err(be->dev,
1279 "dpcm: hw_params BE fixup failed %d\n",
1280 ret);
1281 goto unwind;
1282 }
1283 }
1284
1285 ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params);
1286 if (ret < 0) {
1287 dev_err(dpcm->be->dev,
1288 "dpcm: hw_params BE failed %d\n", ret);
1289 goto unwind;
1290 }
1291
1292 be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
1293 }
1294 return 0;
1295
1296unwind:
1297 /* disable any enabled and non active backends */
1298 list_for_each_entry_continue_reverse(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1299 struct snd_soc_pcm_runtime *be = dpcm->be;
1300 struct snd_pcm_substream *be_substream =
1301 snd_soc_dpcm_get_substream(be, stream);
1302
1303 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1304 continue;
1305
1306 /* only allow hw_free() if no connected FEs are running */
1307 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1308 continue;
1309
1310 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN) &&
1311 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1312 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
1313 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1314 continue;
1315
1316 soc_pcm_hw_free(be_substream);
1317 }
1318
1319 return ret;
1320}
1321
1322int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream,
1323 struct snd_pcm_hw_params *params)
1324{
1325 struct snd_soc_pcm_runtime *fe = substream->private_data;
1326 int ret, stream = substream->stream;
1327
1328 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1329 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1330
1331 memcpy(&fe->dpcm[substream->stream].hw_params, params,
1332 sizeof(struct snd_pcm_hw_params));
1333 ret = dpcm_be_dai_hw_params(fe, substream->stream);
1334 if (ret < 0) {
1335 dev_err(fe->dev,"dpcm: hw_params BE failed %d\n", ret);
1336 goto out;
1337 }
1338
1339 dev_dbg(fe->dev, "dpcm: hw_params FE %s rate %d chan %x fmt %d\n",
1340 fe->dai_link->name, params_rate(params),
1341 params_channels(params), params_format(params));
1342
1343 /* call hw_params on the frontend */
1344 ret = soc_pcm_hw_params(substream, params);
1345 if (ret < 0) {
1346 dev_err(fe->dev,"dpcm: hw_params FE failed %d\n", ret);
1347 dpcm_be_dai_hw_free(fe, stream);
1348 } else
1349 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_PARAMS;
1350
1351out:
1352 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1353 mutex_unlock(&fe->card->mutex);
1354 return ret;
1355}
1356
1357static int dpcm_do_trigger(struct snd_soc_dpcm *dpcm,
1358 struct snd_pcm_substream *substream, int cmd)
1359{
1360 int ret;
1361
1362 dev_dbg(dpcm->be->dev, "dpcm: trigger BE %s cmd %d\n",
1363 dpcm->fe->dai_link->name, cmd);
1364
1365 ret = soc_pcm_trigger(substream, cmd);
1366 if (ret < 0)
1367 dev_err(dpcm->be->dev,"dpcm: trigger BE failed %d\n", ret);
1368
1369 return ret;
1370}
1371
1372int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream, int cmd)
1373{
1374 struct snd_soc_dpcm *dpcm;
1375 int ret = 0;
1376
1377 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1378
1379 struct snd_soc_pcm_runtime *be = dpcm->be;
1380 struct snd_pcm_substream *be_substream =
1381 snd_soc_dpcm_get_substream(be, stream);
1382
1383 /* is this op for this BE ? */
1384 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1385 continue;
1386
1387 switch (cmd) {
1388 case SNDRV_PCM_TRIGGER_START:
1389 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
1390 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1391 continue;
1392
1393 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1394 if (ret)
1395 return ret;
1396
1397 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1398 break;
1399 case SNDRV_PCM_TRIGGER_RESUME:
1400 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND))
1401 continue;
1402
1403 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1404 if (ret)
1405 return ret;
1406
1407 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1408 break;
1409 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1410 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED))
1411 continue;
1412
1413 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1414 if (ret)
1415 return ret;
1416
1417 be->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1418 break;
1419 case SNDRV_PCM_TRIGGER_STOP:
1420 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
1421 continue;
1422
1423 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1424 continue;
1425
1426 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1427 if (ret)
1428 return ret;
1429
1430 be->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
1431 break;
1432 case SNDRV_PCM_TRIGGER_SUSPEND:
1433 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP)
1434 continue;
1435
1436 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1437 continue;
1438
1439 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1440 if (ret)
1441 return ret;
1442
1443 be->dpcm[stream].state = SND_SOC_DPCM_STATE_SUSPEND;
1444 break;
1445 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1446 if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
1447 continue;
1448
1449 if (!snd_soc_dpcm_can_be_free_stop(fe, be, stream))
1450 continue;
1451
1452 ret = dpcm_do_trigger(dpcm, be_substream, cmd);
1453 if (ret)
1454 return ret;
1455
1456 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PAUSED;
1457 break;
1458 }
1459 }
1460
1461 return ret;
1462}
1463EXPORT_SYMBOL_GPL(dpcm_be_dai_trigger);
1464
1465int dpcm_fe_dai_trigger(struct snd_pcm_substream *substream, int cmd)
1466{
1467 struct snd_soc_pcm_runtime *fe = substream->private_data;
1468 int stream = substream->stream, ret;
1469 enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
1470
1471 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1472
1473 switch (trigger) {
1474 case SND_SOC_DPCM_TRIGGER_PRE:
1475 /* call trigger on the frontend before the backend. */
1476
1477 dev_dbg(fe->dev, "dpcm: pre trigger FE %s cmd %d\n",
1478 fe->dai_link->name, cmd);
1479
1480 ret = soc_pcm_trigger(substream, cmd);
1481 if (ret < 0) {
1482 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
1483 goto out;
1484 }
1485
1486 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
1487 break;
1488 case SND_SOC_DPCM_TRIGGER_POST:
1489 /* call trigger on the frontend after the backend. */
1490
1491 ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
1492 if (ret < 0) {
1493 dev_err(fe->dev,"dpcm: trigger FE failed %d\n", ret);
1494 goto out;
1495 }
1496
1497 dev_dbg(fe->dev, "dpcm: post trigger FE %s cmd %d\n",
1498 fe->dai_link->name, cmd);
1499
1500 ret = soc_pcm_trigger(substream, cmd);
1501 break;
1502 default:
1503 dev_err(fe->dev, "dpcm: invalid trigger cmd %d for %s\n", cmd,
1504 fe->dai_link->name);
1505 ret = -EINVAL;
1506 goto out;
1507 }
1508
1509 switch (cmd) {
1510 case SNDRV_PCM_TRIGGER_START:
1511 case SNDRV_PCM_TRIGGER_RESUME:
1512 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1513 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_START;
1514 break;
1515 case SNDRV_PCM_TRIGGER_STOP:
1516 case SNDRV_PCM_TRIGGER_SUSPEND:
1517 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1518 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_STOP;
1519 break;
1520 }
1521
1522out:
1523 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1524 return ret;
1525}
1526
1527static int dpcm_be_dai_prepare(struct snd_soc_pcm_runtime *fe, int stream)
1528{
1529 struct snd_soc_dpcm *dpcm;
1530 int ret = 0;
1531
1532 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1533
1534 struct snd_soc_pcm_runtime *be = dpcm->be;
1535 struct snd_pcm_substream *be_substream =
1536 snd_soc_dpcm_get_substream(be, stream);
1537
1538 /* is this op for this BE ? */
1539 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
1540 continue;
1541
1542 if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_PARAMS) &&
1543 (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
1544 continue;
1545
1546 dev_dbg(be->dev, "dpcm: prepare BE %s\n",
1547 dpcm->fe->dai_link->name);
1548
1549 ret = soc_pcm_prepare(be_substream);
1550 if (ret < 0) {
1551 dev_err(be->dev, "dpcm: backend prepare failed %d\n",
1552 ret);
1553 break;
1554 }
1555
1556 be->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
1557 }
1558 return ret;
1559}
1560
1561int dpcm_fe_dai_prepare(struct snd_pcm_substream *substream)
1562{
1563 struct snd_soc_pcm_runtime *fe = substream->private_data;
1564 int stream = substream->stream, ret = 0;
1565
1566 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1567
1568 dev_dbg(fe->dev, "dpcm: prepare FE %s\n", fe->dai_link->name);
1569
1570 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
1571
1572 /* there is no point preparing this FE if there are no BEs */
1573 if (list_empty(&fe->dpcm[stream].be_clients)) {
1574 dev_err(fe->dev, "dpcm: no backend DAIs enabled for %s\n",
1575 fe->dai_link->name);
1576 ret = -EINVAL;
1577 goto out;
1578 }
1579
1580 ret = dpcm_be_dai_prepare(fe, substream->stream);
1581 if (ret < 0)
1582 goto out;
1583
1584 /* call prepare on the frontend */
1585 ret = soc_pcm_prepare(substream);
1586 if (ret < 0) {
1587 dev_err(fe->dev,"dpcm: prepare FE %s failed\n",
1588 fe->dai_link->name);
1589 goto out;
1590 }
1591
1592 /* run the stream event for each BE */
1593 dpcm_dapm_stream_event(fe, stream, SND_SOC_DAPM_STREAM_START);
1594 fe->dpcm[stream].state = SND_SOC_DPCM_STATE_PREPARE;
1595
1596out:
1597 fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_NO;
1598 mutex_unlock(&fe->card->mutex);
1599
1600 return ret;
1601}
1602
1603
1604int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute)
1605{
1606 struct snd_soc_dpcm *dpcm;
1607 struct list_head *clients =
1608 &fe->dpcm[SNDRV_PCM_STREAM_PLAYBACK].be_clients;
1609
1610 list_for_each_entry(dpcm, clients, list_be) {
1611
1612 struct snd_soc_pcm_runtime *be = dpcm->be;
1613 struct snd_soc_dai *dai = be->codec_dai;
1614 struct snd_soc_dai_driver *drv = dai->driver;
1615
1616 if (be->dai_link->ignore_suspend)
1617 continue;
1618
1619 dev_dbg(be->dev, "BE digital mute %s\n", be->dai_link->name);
1620
1621 if (drv->ops->digital_mute && dai->playback_active)
1622 drv->ops->digital_mute(dai, mute);
1623 }
1624
1625 return 0;
1626}
1627
1628int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream)
1629{
1630 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1631 struct snd_soc_dpcm *dpcm;
1632 struct snd_soc_dapm_widget_list *list;
1633 int ret;
1634 int stream = fe_substream->stream;
1635
1636 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1637 fe->dpcm[stream].runtime = fe_substream->runtime;
1638
1639 if (dpcm_path_get(fe, stream, &list) <= 0) {
1640 dev_warn(fe->dev, "asoc: %s no valid %s route\n",
1641 fe->dai_link->name, stream ? "capture" : "playback");
1642 mutex_unlock(&fe->card->mutex);
1643 return -EINVAL;
1644 }
1645
1646 /* calculate valid and active FE <-> BE dpcms */
1647 dpcm_process_paths(fe, stream, &list, 1);
1648
1649 ret = dpcm_fe_dai_startup(fe_substream);
1650 if (ret < 0) {
1651 /* clean up all links */
1652 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
1653 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
1654
1655 dpcm_be_disconnect(fe, stream);
1656 fe->dpcm[stream].runtime = NULL;
1657 }
1658
1659 dpcm_clear_pending_state(fe, stream);
1660 dpcm_path_put(&list);
1661 mutex_unlock(&fe->card->mutex);
1662 return ret;
1663}
1664
1665int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
1666{
1667 struct snd_soc_pcm_runtime *fe = fe_substream->private_data;
1668 struct snd_soc_dpcm *dpcm;
1669 int stream = fe_substream->stream, ret;
1670
1671 mutex_lock_nested(&fe->card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
1672 ret = dpcm_fe_dai_shutdown(fe_substream);
1673
1674 /* mark FE's links ready to prune */
1675 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
1676 dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
1677
1678 dpcm_be_disconnect(fe, stream);
1679
1680 fe->dpcm[stream].runtime = NULL;
1681 mutex_unlock(&fe->card->mutex);
1682 return ret;
1683}
1684
ddee627c
LG
1685/* create a new pcm */
1686int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
1687{
1688 struct snd_soc_codec *codec = rtd->codec;
1689 struct snd_soc_platform *platform = rtd->platform;
1690 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1691 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1692 struct snd_pcm *pcm;
1693 char new_name[64];
1694 int ret = 0, playback = 0, capture = 0;
1695
01d7584c
LG
1696 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) {
1697 if (cpu_dai->driver->playback.channels_min)
1698 playback = 1;
1699 if (cpu_dai->driver->capture.channels_min)
1700 capture = 1;
1701 } else {
1702 if (codec_dai->driver->playback.channels_min)
1703 playback = 1;
1704 if (codec_dai->driver->capture.channels_min)
1705 capture = 1;
1706 }
1707
1708 /* create the PCM */
1709 if (rtd->dai_link->no_pcm) {
1710 snprintf(new_name, sizeof(new_name), "(%s)",
1711 rtd->dai_link->stream_name);
1712
1713 ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
1714 playback, capture, &pcm);
1715 } else {
1716 if (rtd->dai_link->dynamic)
1717 snprintf(new_name, sizeof(new_name), "%s (*)",
1718 rtd->dai_link->stream_name);
1719 else
1720 snprintf(new_name, sizeof(new_name), "%s %s-%d",
1721 rtd->dai_link->stream_name, codec_dai->name, num);
1722
1723 ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback,
1724 capture, &pcm);
1725 }
ddee627c
LG
1726 if (ret < 0) {
1727 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name);
1728 return ret;
1729 }
01d7584c 1730 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name);
ddee627c
LG
1731
1732 /* DAPM dai link stream work */
1733 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
1734
1735 rtd->pcm = pcm;
1736 pcm->private_data = rtd;
01d7584c
LG
1737
1738 if (rtd->dai_link->no_pcm) {
1739 if (playback)
1740 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
1741 if (capture)
1742 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
1743 goto out;
1744 }
1745
1746 /* ASoC PCM operations */
1747 if (rtd->dai_link->dynamic) {
1748 rtd->ops.open = dpcm_fe_dai_open;
1749 rtd->ops.hw_params = dpcm_fe_dai_hw_params;
1750 rtd->ops.prepare = dpcm_fe_dai_prepare;
1751 rtd->ops.trigger = dpcm_fe_dai_trigger;
1752 rtd->ops.hw_free = dpcm_fe_dai_hw_free;
1753 rtd->ops.close = dpcm_fe_dai_close;
1754 rtd->ops.pointer = soc_pcm_pointer;
1755 } else {
1756 rtd->ops.open = soc_pcm_open;
1757 rtd->ops.hw_params = soc_pcm_hw_params;
1758 rtd->ops.prepare = soc_pcm_prepare;
1759 rtd->ops.trigger = soc_pcm_trigger;
1760 rtd->ops.hw_free = soc_pcm_hw_free;
1761 rtd->ops.close = soc_pcm_close;
1762 rtd->ops.pointer = soc_pcm_pointer;
1763 }
1764
ddee627c 1765 if (platform->driver->ops) {
01d7584c
LG
1766 rtd->ops.ack = platform->driver->ops->ack;
1767 rtd->ops.copy = platform->driver->ops->copy;
1768 rtd->ops.silence = platform->driver->ops->silence;
1769 rtd->ops.page = platform->driver->ops->page;
1770 rtd->ops.mmap = platform->driver->ops->mmap;
ddee627c
LG
1771 }
1772
1773 if (playback)
01d7584c 1774 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &rtd->ops);
ddee627c
LG
1775
1776 if (capture)
01d7584c 1777 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
ddee627c
LG
1778
1779 if (platform->driver->pcm_new) {
1780 ret = platform->driver->pcm_new(rtd);
1781 if (ret < 0) {
1782 pr_err("asoc: platform pcm constructor failed\n");
1783 return ret;
1784 }
1785 }
1786
1787 pcm->private_free = platform->driver->pcm_free;
01d7584c 1788out:
ddee627c
LG
1789 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
1790 cpu_dai->name);
1791 return ret;
1792}
01d7584c
LG
1793
1794/* is the current PCM operation for this FE ? */
1795int snd_soc_dpcm_fe_can_update(struct snd_soc_pcm_runtime *fe, int stream)
1796{
1797 if (fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE)
1798 return 1;
1799 return 0;
1800}
1801EXPORT_SYMBOL_GPL(snd_soc_dpcm_fe_can_update);
1802
1803/* is the current PCM operation for this BE ? */
1804int snd_soc_dpcm_be_can_update(struct snd_soc_pcm_runtime *fe,
1805 struct snd_soc_pcm_runtime *be, int stream)
1806{
1807 if ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_FE) ||
1808 ((fe->dpcm[stream].runtime_update == SND_SOC_DPCM_UPDATE_BE) &&
1809 be->dpcm[stream].runtime_update))
1810 return 1;
1811 return 0;
1812}
1813EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_can_update);
1814
1815/* get the substream for this BE */
1816struct snd_pcm_substream *
1817 snd_soc_dpcm_get_substream(struct snd_soc_pcm_runtime *be, int stream)
1818{
1819 return be->pcm->streams[stream].substream;
1820}
1821EXPORT_SYMBOL_GPL(snd_soc_dpcm_get_substream);
1822
1823/* get the BE runtime state */
1824enum snd_soc_dpcm_state
1825 snd_soc_dpcm_be_get_state(struct snd_soc_pcm_runtime *be, int stream)
1826{
1827 return be->dpcm[stream].state;
1828}
1829EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_get_state);
1830
1831/* set the BE runtime state */
1832void snd_soc_dpcm_be_set_state(struct snd_soc_pcm_runtime *be,
1833 int stream, enum snd_soc_dpcm_state state)
1834{
1835 be->dpcm[stream].state = state;
1836}
1837EXPORT_SYMBOL_GPL(snd_soc_dpcm_be_set_state);
1838
1839/*
1840 * We can only hw_free, stop, pause or suspend a BE DAI if any of it's FE
1841 * are not running, paused or suspended for the specified stream direction.
1842 */
1843int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe,
1844 struct snd_soc_pcm_runtime *be, int stream)
1845{
1846 struct snd_soc_dpcm *dpcm;
1847 int state;
1848
1849 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
1850
1851 if (dpcm->fe == fe)
1852 continue;
1853
1854 state = dpcm->fe->dpcm[stream].state;
1855 if (state == SND_SOC_DPCM_STATE_START ||
1856 state == SND_SOC_DPCM_STATE_PAUSED ||
1857 state == SND_SOC_DPCM_STATE_SUSPEND)
1858 return 0;
1859 }
1860
1861 /* it's safe to free/stop this BE DAI */
1862 return 1;
1863}
1864EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop);
1865
1866/*
1867 * We can only change hw params a BE DAI if any of it's FE are not prepared,
1868 * running, paused or suspended for the specified stream direction.
1869 */
1870int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
1871 struct snd_soc_pcm_runtime *be, int stream)
1872{
1873 struct snd_soc_dpcm *dpcm;
1874 int state;
1875
1876 list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
1877
1878 if (dpcm->fe == fe)
1879 continue;
1880
1881 state = dpcm->fe->dpcm[stream].state;
1882 if (state == SND_SOC_DPCM_STATE_START ||
1883 state == SND_SOC_DPCM_STATE_PAUSED ||
1884 state == SND_SOC_DPCM_STATE_SUSPEND ||
1885 state == SND_SOC_DPCM_STATE_PREPARE)
1886 return 0;
1887 }
1888
1889 /* it's safe to change hw_params */
1890 return 1;
1891}
1892EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params);
This page took 0.13763 seconds and 5 git commands to generate.