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