aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenoit Cousson <bcousson@baylibre.com>2014-07-08 17:19:35 -0400
committerMark Brown <broonie@linaro.org>2014-07-16 18:04:52 -0400
commit2e5894d73789ee60d4d406fd3342a9a5152ec23c (patch)
tree76980121719de615fba7495eebd3b526557797b9
parent88bd870f02dff5c9445286e185f21873f25a977f (diff)
ASoC: pcm: Add support for DAI multicodec
Add multicodec support in soc-pcm.c Signed-off-by: Benoit Cousson <bcousson@baylibre.com> Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com> Signed-off-by: Fabien Parent <fparent@baylibre.com> Tested-by: Lars-Peter Clausen <lars@metafoo.de> Reviewed-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--sound/soc/soc-pcm.c534
1 files changed, 368 insertions, 166 deletions
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 3bf0355ca30f..ec56d1831a86 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -47,22 +47,26 @@
47void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream) 47void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
48{ 48{
49 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 49 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
50 struct snd_soc_dai *codec_dai = rtd->codec_dai; 50 int i;
51 51
52 lockdep_assert_held(&rtd->pcm_mutex); 52 lockdep_assert_held(&rtd->pcm_mutex);
53 53
54 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 54 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
55 cpu_dai->playback_active++; 55 cpu_dai->playback_active++;
56 codec_dai->playback_active++; 56 for (i = 0; i < rtd->num_codecs; i++)
57 rtd->codec_dais[i]->playback_active++;
57 } else { 58 } else {
58 cpu_dai->capture_active++; 59 cpu_dai->capture_active++;
59 codec_dai->capture_active++; 60 for (i = 0; i < rtd->num_codecs; i++)
61 rtd->codec_dais[i]->capture_active++;
60 } 62 }
61 63
62 cpu_dai->active++; 64 cpu_dai->active++;
63 codec_dai->active++;
64 cpu_dai->component->active++; 65 cpu_dai->component->active++;
65 codec_dai->component->active++; 66 for (i = 0; i < rtd->num_codecs; i++) {
67 rtd->codec_dais[i]->active++;
68 rtd->codec_dais[i]->component->active++;
69 }
66} 70}
67 71
68/** 72/**
@@ -78,22 +82,26 @@ void snd_soc_runtime_activate(struct snd_soc_pcm_runtime *rtd, int stream)
78void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream) 82void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
79{ 83{
80 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 84 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
81 struct snd_soc_dai *codec_dai = rtd->codec_dai; 85 int i;
82 86
83 lockdep_assert_held(&rtd->pcm_mutex); 87 lockdep_assert_held(&rtd->pcm_mutex);
84 88
85 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 89 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
86 cpu_dai->playback_active--; 90 cpu_dai->playback_active--;
87 codec_dai->playback_active--; 91 for (i = 0; i < rtd->num_codecs; i++)
92 rtd->codec_dais[i]->playback_active--;
88 } else { 93 } else {
89 cpu_dai->capture_active--; 94 cpu_dai->capture_active--;
90 codec_dai->capture_active--; 95 for (i = 0; i < rtd->num_codecs; i++)
96 rtd->codec_dais[i]->capture_active--;
91 } 97 }
92 98
93 cpu_dai->active--; 99 cpu_dai->active--;
94 codec_dai->active--;
95 cpu_dai->component->active--; 100 cpu_dai->component->active--;
96 codec_dai->component->active--; 101 for (i = 0; i < rtd->num_codecs; i++) {
102 rtd->codec_dais[i]->component->active--;
103 rtd->codec_dais[i]->active--;
104 }
97} 105}
98 106
99/** 107/**
@@ -107,11 +115,16 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream)
107 */ 115 */
108bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd) 116bool snd_soc_runtime_ignore_pmdown_time(struct snd_soc_pcm_runtime *rtd)
109{ 117{
118 int i;
119 bool ignore = true;
120
110 if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time) 121 if (!rtd->pmdown_time || rtd->dai_link->ignore_pmdown_time)
111 return true; 122 return true;
112 123
113 return rtd->cpu_dai->component->ignore_pmdown_time && 124 for (i = 0; i < rtd->num_codecs; i++)
114 rtd->codec_dai->component->ignore_pmdown_time; 125 ignore &= rtd->codec_dais[i]->component->ignore_pmdown_time;
126
127 return rtd->cpu_dai->component->ignore_pmdown_time && ignore;
115} 128}
116 129
117/** 130/**
@@ -222,8 +235,7 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream,
222{ 235{
223 struct snd_soc_pcm_runtime *rtd = substream->private_data; 236 struct snd_soc_pcm_runtime *rtd = substream->private_data;
224 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 237 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
225 struct snd_soc_dai *codec_dai = rtd->codec_dai; 238 unsigned int rate, channels, sample_bits, symmetry, i;
226 unsigned int rate, channels, sample_bits, symmetry;
227 239
228 rate = params_rate(params); 240 rate = params_rate(params);
229 channels = params_channels(params); 241 channels = params_channels(params);
@@ -231,8 +243,11 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream,
231 243
232 /* reject unmatched parameters when applying symmetry */ 244 /* reject unmatched parameters when applying symmetry */
233 symmetry = cpu_dai->driver->symmetric_rates || 245 symmetry = cpu_dai->driver->symmetric_rates ||
234 codec_dai->driver->symmetric_rates ||
235 rtd->dai_link->symmetric_rates; 246 rtd->dai_link->symmetric_rates;
247
248 for (i = 0; i < rtd->num_codecs; i++)
249 symmetry |= rtd->codec_dais[i]->driver->symmetric_rates;
250
236 if (symmetry && cpu_dai->rate && cpu_dai->rate != rate) { 251 if (symmetry && cpu_dai->rate && cpu_dai->rate != rate) {
237 dev_err(rtd->dev, "ASoC: unmatched rate symmetry: %d - %d\n", 252 dev_err(rtd->dev, "ASoC: unmatched rate symmetry: %d - %d\n",
238 cpu_dai->rate, rate); 253 cpu_dai->rate, rate);
@@ -240,8 +255,11 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream,
240 } 255 }
241 256
242 symmetry = cpu_dai->driver->symmetric_channels || 257 symmetry = cpu_dai->driver->symmetric_channels ||
243 codec_dai->driver->symmetric_channels ||
244 rtd->dai_link->symmetric_channels; 258 rtd->dai_link->symmetric_channels;
259
260 for (i = 0; i < rtd->num_codecs; i++)
261 symmetry |= rtd->codec_dais[i]->driver->symmetric_channels;
262
245 if (symmetry && cpu_dai->channels && cpu_dai->channels != channels) { 263 if (symmetry && cpu_dai->channels && cpu_dai->channels != channels) {
246 dev_err(rtd->dev, "ASoC: unmatched channel symmetry: %d - %d\n", 264 dev_err(rtd->dev, "ASoC: unmatched channel symmetry: %d - %d\n",
247 cpu_dai->channels, channels); 265 cpu_dai->channels, channels);
@@ -249,8 +267,11 @@ static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream,
249 } 267 }
250 268
251 symmetry = cpu_dai->driver->symmetric_samplebits || 269 symmetry = cpu_dai->driver->symmetric_samplebits ||
252 codec_dai->driver->symmetric_samplebits ||
253 rtd->dai_link->symmetric_samplebits; 270 rtd->dai_link->symmetric_samplebits;
271
272 for (i = 0; i < rtd->num_codecs; i++)
273 symmetry |= rtd->codec_dais[i]->driver->symmetric_samplebits;
274
254 if (symmetry && cpu_dai->sample_bits && cpu_dai->sample_bits != sample_bits) { 275 if (symmetry && cpu_dai->sample_bits && cpu_dai->sample_bits != sample_bits) {
255 dev_err(rtd->dev, "ASoC: unmatched sample bits symmetry: %d - %d\n", 276 dev_err(rtd->dev, "ASoC: unmatched sample bits symmetry: %d - %d\n",
256 cpu_dai->sample_bits, sample_bits); 277 cpu_dai->sample_bits, sample_bits);
@@ -264,15 +285,20 @@ static bool soc_pcm_has_symmetry(struct snd_pcm_substream *substream)
264{ 285{
265 struct snd_soc_pcm_runtime *rtd = substream->private_data; 286 struct snd_soc_pcm_runtime *rtd = substream->private_data;
266 struct snd_soc_dai_driver *cpu_driver = rtd->cpu_dai->driver; 287 struct snd_soc_dai_driver *cpu_driver = rtd->cpu_dai->driver;
267 struct snd_soc_dai_driver *codec_driver = rtd->codec_dai->driver;
268 struct snd_soc_dai_link *link = rtd->dai_link; 288 struct snd_soc_dai_link *link = rtd->dai_link;
289 unsigned int symmetry, i;
290
291 symmetry = cpu_driver->symmetric_rates || link->symmetric_rates ||
292 cpu_driver->symmetric_channels || link->symmetric_channels ||
293 cpu_driver->symmetric_samplebits || link->symmetric_samplebits;
269 294
270 return cpu_driver->symmetric_rates || codec_driver->symmetric_rates || 295 for (i = 0; i < rtd->num_codecs; i++)
271 link->symmetric_rates || cpu_driver->symmetric_channels || 296 symmetry = symmetry ||
272 codec_driver->symmetric_channels || link->symmetric_channels || 297 rtd->codec_dais[i]->driver->symmetric_rates ||
273 cpu_driver->symmetric_samplebits || 298 rtd->codec_dais[i]->driver->symmetric_channels ||
274 codec_driver->symmetric_samplebits || 299 rtd->codec_dais[i]->driver->symmetric_samplebits;
275 link->symmetric_samplebits; 300
301 return symmetry;
276} 302}
277 303
278/* 304/*
@@ -284,9 +310,9 @@ static int sample_sizes[] = {
284 24, 32, 310 24, 32,
285}; 311};
286 312
287static void soc_pcm_set_msb(struct snd_pcm_substream *substream, 313static void soc_pcm_set_msb(struct snd_pcm_substream *substream, int bits)
288 struct snd_soc_dai *dai, int bits)
289{ 314{
315 struct snd_soc_pcm_runtime *rtd = substream->private_data;
290 int ret, i; 316 int ret, i;
291 317
292 if (!bits) 318 if (!bits)
@@ -299,7 +325,7 @@ static void soc_pcm_set_msb(struct snd_pcm_substream *substream,
299 ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 325 ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0,
300 sample_sizes[i], bits); 326 sample_sizes[i], bits);
301 if (ret != 0) 327 if (ret != 0)
302 dev_warn(dai->dev, 328 dev_warn(rtd->dev,
303 "ASoC: Failed to set MSB %d/%d: %d\n", 329 "ASoC: Failed to set MSB %d/%d: %d\n",
304 bits, sample_sizes[i], ret); 330 bits, sample_sizes[i], ret);
305 } 331 }
@@ -309,47 +335,95 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream)
309{ 335{
310 struct snd_soc_pcm_runtime *rtd = substream->private_data; 336 struct snd_soc_pcm_runtime *rtd = substream->private_data;
311 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 337 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
312 struct snd_soc_dai *codec_dai = rtd->codec_dai; 338 struct snd_soc_dai *codec_dai;
339 int i;
313 unsigned int bits = 0, cpu_bits; 340 unsigned int bits = 0, cpu_bits;
314 341
315 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 342 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
316 bits = codec_dai->driver->playback.sig_bits; 343 for (i = 0; i < rtd->num_codecs; i++) {
344 codec_dai = rtd->codec_dais[i];
345 if (codec_dai->driver->playback.sig_bits == 0) {
346 bits = 0;
347 break;
348 }
349 bits = max(codec_dai->driver->playback.sig_bits, bits);
350 }
317 cpu_bits = cpu_dai->driver->playback.sig_bits; 351 cpu_bits = cpu_dai->driver->playback.sig_bits;
318 } else { 352 } else {
319 bits = codec_dai->driver->capture.sig_bits; 353 for (i = 0; i < rtd->num_codecs; i++) {
354 codec_dai = rtd->codec_dais[i];
355 if (codec_dai->driver->playback.sig_bits == 0) {
356 bits = 0;
357 break;
358 }
359 bits = max(codec_dai->driver->capture.sig_bits, bits);
360 }
320 cpu_bits = cpu_dai->driver->capture.sig_bits; 361 cpu_bits = cpu_dai->driver->capture.sig_bits;
321 } 362 }
322 363
323 soc_pcm_set_msb(substream, codec_dai, bits); 364 soc_pcm_set_msb(substream, bits);
324 soc_pcm_set_msb(substream, cpu_dai, cpu_bits); 365 soc_pcm_set_msb(substream, cpu_bits);
325} 366}
326 367
327static void soc_pcm_init_runtime_hw(struct snd_pcm_runtime *runtime, 368static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
328 struct snd_soc_pcm_stream *codec_stream,
329 struct snd_soc_pcm_stream *cpu_stream)
330{ 369{
370 struct snd_pcm_runtime *runtime = substream->runtime;
331 struct snd_pcm_hardware *hw = &runtime->hw; 371 struct snd_pcm_hardware *hw = &runtime->hw;
372 struct snd_soc_pcm_runtime *rtd = substream->private_data;
373 struct snd_soc_dai_driver *cpu_dai_drv = rtd->cpu_dai->driver;
374 struct snd_soc_dai_driver *codec_dai_drv;
375 struct snd_soc_pcm_stream *codec_stream;
376 struct snd_soc_pcm_stream *cpu_stream;
377 unsigned int chan_min = 0, chan_max = UINT_MAX;
378 unsigned int rate_min = 0, rate_max = UINT_MAX;
379 unsigned int rates = UINT_MAX;
380 u64 formats = ULLONG_MAX;
381 int i;
332 382
333 hw->channels_min = max(codec_stream->channels_min, 383 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
334 cpu_stream->channels_min); 384 cpu_stream = &cpu_dai_drv->playback;
335 hw->channels_max = min(codec_stream->channels_max,
336 cpu_stream->channels_max);
337 if (hw->formats)
338 hw->formats &= codec_stream->formats & cpu_stream->formats;
339 else 385 else
340 hw->formats = codec_stream->formats & cpu_stream->formats; 386 cpu_stream = &cpu_dai_drv->capture;
341 hw->rates = snd_pcm_rate_mask_intersect(codec_stream->rates,
342 cpu_stream->rates);
343 387
344 hw->rate_min = 0; 388 /* first calculate min/max only for CODECs in the DAI link */
345 hw->rate_max = UINT_MAX; 389 for (i = 0; i < rtd->num_codecs; i++) {
390 codec_dai_drv = rtd->codec_dais[i]->driver;
391 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
392 codec_stream = &codec_dai_drv->playback;
393 else
394 codec_stream = &codec_dai_drv->capture;
395 chan_min = max(chan_min, codec_stream->channels_min);
396 chan_max = min(chan_max, codec_stream->channels_max);
397 rate_min = max(rate_min, codec_stream->rate_min);
398 rate_max = min_not_zero(rate_max, codec_stream->rate_max);
399 formats &= codec_stream->formats;
400 rates = snd_pcm_rate_mask_intersect(codec_stream->rates, rates);
401 }
402
403 /*
404 * chan min/max cannot be enforced if there are multiple CODEC DAIs
405 * connected to a single CPU DAI, use CPU DAI's directly and let
406 * channel allocation be fixed up later
407 */
408 if (rtd->num_codecs > 1) {
409 chan_min = cpu_stream->channels_min;
410 chan_max = cpu_stream->channels_max;
411 }
412
413 hw->channels_min = max(chan_min, cpu_stream->channels_min);
414 hw->channels_max = min(chan_max, cpu_stream->channels_max);
415 if (hw->formats)
416 hw->formats &= formats & cpu_stream->formats;
417 else
418 hw->formats = formats & cpu_stream->formats;
419 hw->rates = snd_pcm_rate_mask_intersect(rates, cpu_stream->rates);
346 420
347 snd_pcm_limit_hw_rates(runtime); 421 snd_pcm_limit_hw_rates(runtime);
348 422
349 hw->rate_min = max(hw->rate_min, cpu_stream->rate_min); 423 hw->rate_min = max(hw->rate_min, cpu_stream->rate_min);
350 hw->rate_min = max(hw->rate_min, codec_stream->rate_min); 424 hw->rate_min = max(hw->rate_min, rate_min);
351 hw->rate_max = min_not_zero(hw->rate_max, cpu_stream->rate_max); 425 hw->rate_max = min_not_zero(hw->rate_max, cpu_stream->rate_max);
352 hw->rate_max = min_not_zero(hw->rate_max, codec_stream->rate_max); 426 hw->rate_max = min_not_zero(hw->rate_max, rate_max);
353} 427}
354 428
355/* 429/*
@@ -363,15 +437,16 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
363 struct snd_pcm_runtime *runtime = substream->runtime; 437 struct snd_pcm_runtime *runtime = substream->runtime;
364 struct snd_soc_platform *platform = rtd->platform; 438 struct snd_soc_platform *platform = rtd->platform;
365 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 439 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
366 struct snd_soc_dai *codec_dai = rtd->codec_dai; 440 struct snd_soc_dai *codec_dai;
367 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver; 441 const char *codec_dai_name = "multicodec";
368 struct snd_soc_dai_driver *codec_dai_drv = codec_dai->driver; 442 int i, ret = 0;
369 int ret = 0;
370 443
371 pinctrl_pm_select_default_state(cpu_dai->dev); 444 pinctrl_pm_select_default_state(cpu_dai->dev);
372 pinctrl_pm_select_default_state(codec_dai->dev); 445 for (i = 0; i < rtd->num_codecs; i++)
446 pinctrl_pm_select_default_state(rtd->codec_dais[i]->dev);
373 pm_runtime_get_sync(cpu_dai->dev); 447 pm_runtime_get_sync(cpu_dai->dev);
374 pm_runtime_get_sync(codec_dai->dev); 448 for (i = 0; i < rtd->num_codecs; i++)
449 pm_runtime_get_sync(rtd->codec_dais[i]->dev);
375 pm_runtime_get_sync(platform->dev); 450 pm_runtime_get_sync(platform->dev);
376 451
377 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 452 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
@@ -395,13 +470,23 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
395 } 470 }
396 } 471 }
397 472
398 if (codec_dai->driver->ops && codec_dai->driver->ops->startup) { 473 for (i = 0; i < rtd->num_codecs; i++) {
399 ret = codec_dai->driver->ops->startup(substream, codec_dai); 474 codec_dai = rtd->codec_dais[i];
400 if (ret < 0) { 475 if (codec_dai->driver->ops && codec_dai->driver->ops->startup) {
401 dev_err(codec_dai->dev, "ASoC: can't open codec" 476 ret = codec_dai->driver->ops->startup(substream,
402 " %s: %d\n", codec_dai->name, ret); 477 codec_dai);
403 goto codec_dai_err; 478 if (ret < 0) {
479 dev_err(codec_dai->dev,
480 "ASoC: can't open codec %s: %d\n",
481 codec_dai->name, ret);
482 goto codec_dai_err;
483 }
404 } 484 }
485
486 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
487 codec_dai->tx_mask = 0;
488 else
489 codec_dai->rx_mask = 0;
405 } 490 }
406 491
407 if (rtd->dai_link->ops && rtd->dai_link->ops->startup) { 492 if (rtd->dai_link->ops && rtd->dai_link->ops->startup) {
@@ -418,13 +503,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
418 goto dynamic; 503 goto dynamic;
419 504
420 /* Check that the codec and cpu DAIs are compatible */ 505 /* Check that the codec and cpu DAIs are compatible */
421 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 506 soc_pcm_init_runtime_hw(substream);
422 soc_pcm_init_runtime_hw(runtime, &codec_dai_drv->playback, 507
423 &cpu_dai_drv->playback); 508 if (rtd->num_codecs == 1)
424 } else { 509 codec_dai_name = rtd->codec_dai->name;
425 soc_pcm_init_runtime_hw(runtime, &codec_dai_drv->capture,
426 &cpu_dai_drv->capture);
427 }
428 510
429 if (soc_pcm_has_symmetry(substream)) 511 if (soc_pcm_has_symmetry(substream))
430 runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX; 512 runtime->hw.info |= SNDRV_PCM_INFO_JOINT_DUPLEX;
@@ -432,18 +514,18 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
432 ret = -EINVAL; 514 ret = -EINVAL;
433 if (!runtime->hw.rates) { 515 if (!runtime->hw.rates) {
434 printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n", 516 printk(KERN_ERR "ASoC: %s <-> %s No matching rates\n",
435 codec_dai->name, cpu_dai->name); 517 codec_dai_name, cpu_dai->name);
436 goto config_err; 518 goto config_err;
437 } 519 }
438 if (!runtime->hw.formats) { 520 if (!runtime->hw.formats) {
439 printk(KERN_ERR "ASoC: %s <-> %s No matching formats\n", 521 printk(KERN_ERR "ASoC: %s <-> %s No matching formats\n",
440 codec_dai->name, cpu_dai->name); 522 codec_dai_name, cpu_dai->name);
441 goto config_err; 523 goto config_err;
442 } 524 }
443 if (!runtime->hw.channels_min || !runtime->hw.channels_max || 525 if (!runtime->hw.channels_min || !runtime->hw.channels_max ||
444 runtime->hw.channels_min > runtime->hw.channels_max) { 526 runtime->hw.channels_min > runtime->hw.channels_max) {
445 printk(KERN_ERR "ASoC: %s <-> %s No matching channels\n", 527 printk(KERN_ERR "ASoC: %s <-> %s No matching channels\n",
446 codec_dai->name, cpu_dai->name); 528 codec_dai_name, cpu_dai->name);
447 goto config_err; 529 goto config_err;
448 } 530 }
449 531
@@ -456,14 +538,17 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
456 goto config_err; 538 goto config_err;
457 } 539 }
458 540
459 if (codec_dai->active) { 541 for (i = 0; i < rtd->num_codecs; i++) {
460 ret = soc_pcm_apply_symmetry(substream, codec_dai); 542 if (rtd->codec_dais[i]->active) {
461 if (ret != 0) 543 ret = soc_pcm_apply_symmetry(substream,
462 goto config_err; 544 rtd->codec_dais[i]);
545 if (ret != 0)
546 goto config_err;
547 }
463 } 548 }
464 549
465 pr_debug("ASoC: %s <-> %s info:\n", 550 pr_debug("ASoC: %s <-> %s info:\n",
466 codec_dai->name, cpu_dai->name); 551 codec_dai_name, cpu_dai->name);
467 pr_debug("ASoC: rate mask 0x%x\n", runtime->hw.rates); 552 pr_debug("ASoC: rate mask 0x%x\n", runtime->hw.rates);
468 pr_debug("ASoC: min ch %d max ch %d\n", runtime->hw.channels_min, 553 pr_debug("ASoC: min ch %d max ch %d\n", runtime->hw.channels_min,
469 runtime->hw.channels_max); 554 runtime->hw.channels_max);
@@ -482,10 +567,15 @@ config_err:
482 rtd->dai_link->ops->shutdown(substream); 567 rtd->dai_link->ops->shutdown(substream);
483 568
484machine_err: 569machine_err:
485 if (codec_dai->driver->ops->shutdown) 570 i = rtd->num_codecs;
486 codec_dai->driver->ops->shutdown(substream, codec_dai);
487 571
488codec_dai_err: 572codec_dai_err:
573 while (--i >= 0) {
574 codec_dai = rtd->codec_dais[i];
575 if (codec_dai->driver->ops->shutdown)
576 codec_dai->driver->ops->shutdown(substream, codec_dai);
577 }
578
489 if (platform->driver->ops && platform->driver->ops->close) 579 if (platform->driver->ops && platform->driver->ops->close)
490 platform->driver->ops->close(substream); 580 platform->driver->ops->close(substream);
491 581
@@ -496,10 +586,13 @@ out:
496 mutex_unlock(&rtd->pcm_mutex); 586 mutex_unlock(&rtd->pcm_mutex);
497 587
498 pm_runtime_put(platform->dev); 588 pm_runtime_put(platform->dev);
499 pm_runtime_put(codec_dai->dev); 589 for (i = 0; i < rtd->num_codecs; i++)
590 pm_runtime_put(rtd->codec_dais[i]->dev);
500 pm_runtime_put(cpu_dai->dev); 591 pm_runtime_put(cpu_dai->dev);
501 if (!codec_dai->active) 592 for (i = 0; i < rtd->num_codecs; i++) {
502 pinctrl_pm_select_sleep_state(codec_dai->dev); 593 if (!rtd->codec_dais[i]->active)
594 pinctrl_pm_select_sleep_state(rtd->codec_dais[i]->dev);
595 }
503 if (!cpu_dai->active) 596 if (!cpu_dai->active)
504 pinctrl_pm_select_sleep_state(cpu_dai->dev); 597 pinctrl_pm_select_sleep_state(cpu_dai->dev);
505 598
@@ -515,7 +608,7 @@ static void close_delayed_work(struct work_struct *work)
515{ 608{
516 struct snd_soc_pcm_runtime *rtd = 609 struct snd_soc_pcm_runtime *rtd =
517 container_of(work, struct snd_soc_pcm_runtime, delayed_work.work); 610 container_of(work, struct snd_soc_pcm_runtime, delayed_work.work);
518 struct snd_soc_dai *codec_dai = rtd->codec_dai; 611 struct snd_soc_dai *codec_dai = rtd->codec_dais[0];
519 612
520 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 613 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
521 614
@@ -544,7 +637,8 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
544 struct snd_soc_pcm_runtime *rtd = substream->private_data; 637 struct snd_soc_pcm_runtime *rtd = substream->private_data;
545 struct snd_soc_platform *platform = rtd->platform; 638 struct snd_soc_platform *platform = rtd->platform;
546 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 639 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
547 struct snd_soc_dai *codec_dai = rtd->codec_dai; 640 struct snd_soc_dai *codec_dai;
641 int i;
548 642
549 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 643 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
550 644
@@ -554,14 +648,20 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
554 if (!cpu_dai->active) 648 if (!cpu_dai->active)
555 cpu_dai->rate = 0; 649 cpu_dai->rate = 0;
556 650
557 if (!codec_dai->active) 651 for (i = 0; i < rtd->num_codecs; i++) {
558 codec_dai->rate = 0; 652 codec_dai = rtd->codec_dais[i];
653 if (!codec_dai->active)
654 codec_dai->rate = 0;
655 }
559 656
560 if (cpu_dai->driver->ops->shutdown) 657 if (cpu_dai->driver->ops->shutdown)
561 cpu_dai->driver->ops->shutdown(substream, cpu_dai); 658 cpu_dai->driver->ops->shutdown(substream, cpu_dai);
562 659
563 if (codec_dai->driver->ops->shutdown) 660 for (i = 0; i < rtd->num_codecs; i++) {
564 codec_dai->driver->ops->shutdown(substream, codec_dai); 661 codec_dai = rtd->codec_dais[i];
662 if (codec_dai->driver->ops->shutdown)
663 codec_dai->driver->ops->shutdown(substream, codec_dai);
664 }
565 665
566 if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown) 666 if (rtd->dai_link->ops && rtd->dai_link->ops->shutdown)
567 rtd->dai_link->ops->shutdown(substream); 667 rtd->dai_link->ops->shutdown(substream);
@@ -591,10 +691,13 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
591 mutex_unlock(&rtd->pcm_mutex); 691 mutex_unlock(&rtd->pcm_mutex);
592 692
593 pm_runtime_put(platform->dev); 693 pm_runtime_put(platform->dev);
594 pm_runtime_put(codec_dai->dev); 694 for (i = 0; i < rtd->num_codecs; i++)
695 pm_runtime_put(rtd->codec_dais[i]->dev);
595 pm_runtime_put(cpu_dai->dev); 696 pm_runtime_put(cpu_dai->dev);
596 if (!codec_dai->active) 697 for (i = 0; i < rtd->num_codecs; i++) {
597 pinctrl_pm_select_sleep_state(codec_dai->dev); 698 if (!rtd->codec_dais[i]->active)
699 pinctrl_pm_select_sleep_state(rtd->codec_dais[i]->dev);
700 }
598 if (!cpu_dai->active) 701 if (!cpu_dai->active)
599 pinctrl_pm_select_sleep_state(cpu_dai->dev); 702 pinctrl_pm_select_sleep_state(cpu_dai->dev);
600 703
@@ -611,8 +714,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
611 struct snd_soc_pcm_runtime *rtd = substream->private_data; 714 struct snd_soc_pcm_runtime *rtd = substream->private_data;
612 struct snd_soc_platform *platform = rtd->platform; 715 struct snd_soc_platform *platform = rtd->platform;
613 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 716 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
614 struct snd_soc_dai *codec_dai = rtd->codec_dai; 717 struct snd_soc_dai *codec_dai;
615 int ret = 0; 718 int i, ret = 0;
616 719
617 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 720 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
618 721
@@ -634,12 +737,16 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
634 } 737 }
635 } 738 }
636 739
637 if (codec_dai->driver->ops && codec_dai->driver->ops->prepare) { 740 for (i = 0; i < rtd->num_codecs; i++) {
638 ret = codec_dai->driver->ops->prepare(substream, codec_dai); 741 codec_dai = rtd->codec_dais[i];
639 if (ret < 0) { 742 if (codec_dai->driver->ops && codec_dai->driver->ops->prepare) {
640 dev_err(codec_dai->dev, "ASoC: DAI prepare error: %d\n", 743 ret = codec_dai->driver->ops->prepare(substream,
641 ret); 744 codec_dai);
642 goto out; 745 if (ret < 0) {
746 dev_err(codec_dai->dev,
747 "ASoC: DAI prepare error: %d\n", ret);
748 goto out;
749 }
643 } 750 }
644 } 751 }
645 752
@@ -662,13 +769,26 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
662 snd_soc_dapm_stream_event(rtd, substream->stream, 769 snd_soc_dapm_stream_event(rtd, substream->stream,
663 SND_SOC_DAPM_STREAM_START); 770 SND_SOC_DAPM_STREAM_START);
664 771
665 snd_soc_dai_digital_mute(codec_dai, 0, substream->stream); 772 for (i = 0; i < rtd->num_codecs; i++)
773 snd_soc_dai_digital_mute(rtd->codec_dais[i], 0,
774 substream->stream);
666 775
667out: 776out:
668 mutex_unlock(&rtd->pcm_mutex); 777 mutex_unlock(&rtd->pcm_mutex);
669 return ret; 778 return ret;
670} 779}
671 780
781static void soc_pcm_codec_params_fixup(struct snd_pcm_hw_params *params,
782 unsigned int mask)
783{
784 struct snd_interval *interval;
785 int channels = hweight_long(mask);
786
787 interval = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS);
788 interval->min = channels;
789 interval->max = channels;
790}
791
672/* 792/*
673 * Called by ALSA when the hardware params are set by application. This 793 * Called by ALSA when the hardware params are set by application. This
674 * function can also be called multiple times and can allocate buffers 794 * function can also be called multiple times and can allocate buffers
@@ -680,8 +800,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
680 struct snd_soc_pcm_runtime *rtd = substream->private_data; 800 struct snd_soc_pcm_runtime *rtd = substream->private_data;
681 struct snd_soc_platform *platform = rtd->platform; 801 struct snd_soc_platform *platform = rtd->platform;
682 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 802 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
683 struct snd_soc_dai *codec_dai = rtd->codec_dai; 803 int i, ret = 0;
684 int ret = 0;
685 804
686 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 805 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
687 806
@@ -698,13 +817,37 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
698 } 817 }
699 } 818 }
700 819
701 if (codec_dai->driver->ops && codec_dai->driver->ops->hw_params) { 820 for (i = 0; i < rtd->num_codecs; i++) {
702 ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); 821 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
703 if (ret < 0) { 822 struct snd_pcm_hw_params codec_params;
704 dev_err(codec_dai->dev, "ASoC: can't set %s hw params:" 823
705 " %d\n", codec_dai->name, ret); 824 /* copy params for each codec */
706 goto codec_err; 825 codec_params = *params;
826
827 /* fixup params based on TDM slot masks */
828 if (codec_dai->tx_mask)
829 soc_pcm_codec_params_fixup(&codec_params,
830 codec_dai->tx_mask);
831 if (codec_dai->rx_mask)
832 soc_pcm_codec_params_fixup(&codec_params,
833 codec_dai->rx_mask);
834
835 if (codec_dai->driver->ops &&
836 codec_dai->driver->ops->hw_params) {
837 ret = codec_dai->driver->ops->hw_params(substream,
838 &codec_params, codec_dai);
839 if (ret < 0) {
840 dev_err(codec_dai->dev,
841 "ASoC: can't set %s hw params: %d\n",
842 codec_dai->name, ret);
843 goto codec_err;
844 }
707 } 845 }
846
847 codec_dai->rate = params_rate(&codec_params);
848 codec_dai->channels = params_channels(&codec_params);
849 codec_dai->sample_bits = snd_pcm_format_physical_width(
850 params_format(&codec_params));
708 } 851 }
709 852
710 if (cpu_dai->driver->ops && cpu_dai->driver->ops->hw_params) { 853 if (cpu_dai->driver->ops && cpu_dai->driver->ops->hw_params) {
@@ -731,11 +874,6 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
731 cpu_dai->sample_bits = 874 cpu_dai->sample_bits =
732 snd_pcm_format_physical_width(params_format(params)); 875 snd_pcm_format_physical_width(params_format(params));
733 876
734 codec_dai->rate = params_rate(params);
735 codec_dai->channels = params_channels(params);
736 codec_dai->sample_bits =
737 snd_pcm_format_physical_width(params_format(params));
738
739out: 877out:
740 mutex_unlock(&rtd->pcm_mutex); 878 mutex_unlock(&rtd->pcm_mutex);
741 return ret; 879 return ret;
@@ -745,10 +883,16 @@ platform_err:
745 cpu_dai->driver->ops->hw_free(substream, cpu_dai); 883 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
746 884
747interface_err: 885interface_err:
748 if (codec_dai->driver->ops && codec_dai->driver->ops->hw_free) 886 i = rtd->num_codecs;
749 codec_dai->driver->ops->hw_free(substream, codec_dai);
750 887
751codec_err: 888codec_err:
889 while (--i >= 0) {
890 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
891 if (codec_dai->driver->ops && codec_dai->driver->ops->hw_free)
892 codec_dai->driver->ops->hw_free(substream, codec_dai);
893 codec_dai->rate = 0;
894 }
895
752 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free) 896 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
753 rtd->dai_link->ops->hw_free(substream); 897 rtd->dai_link->ops->hw_free(substream);
754 898
@@ -764,8 +908,9 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
764 struct snd_soc_pcm_runtime *rtd = substream->private_data; 908 struct snd_soc_pcm_runtime *rtd = substream->private_data;
765 struct snd_soc_platform *platform = rtd->platform; 909 struct snd_soc_platform *platform = rtd->platform;
766 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 910 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
767 struct snd_soc_dai *codec_dai = rtd->codec_dai; 911 struct snd_soc_dai *codec_dai;
768 bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 912 bool playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
913 int i;
769 914
770 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass); 915 mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
771 916
@@ -776,16 +921,22 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
776 cpu_dai->sample_bits = 0; 921 cpu_dai->sample_bits = 0;
777 } 922 }
778 923
779 if (codec_dai->active == 1) { 924 for (i = 0; i < rtd->num_codecs; i++) {
780 codec_dai->rate = 0; 925 codec_dai = rtd->codec_dais[i];
781 codec_dai->channels = 0; 926 if (codec_dai->active == 1) {
782 codec_dai->sample_bits = 0; 927 codec_dai->rate = 0;
928 codec_dai->channels = 0;
929 codec_dai->sample_bits = 0;
930 }
783 } 931 }
784 932
785 /* apply codec digital mute */ 933 /* apply codec digital mute */
786 if ((playback && codec_dai->playback_active == 1) || 934 for (i = 0; i < rtd->num_codecs; i++) {
787 (!playback && codec_dai->capture_active == 1)) 935 if ((playback && rtd->codec_dais[i]->playback_active == 1) ||
788 snd_soc_dai_digital_mute(codec_dai, 1, substream->stream); 936 (!playback && rtd->codec_dais[i]->capture_active == 1))
937 snd_soc_dai_digital_mute(rtd->codec_dais[i], 1,
938 substream->stream);
939 }
789 940
790 /* free any machine hw params */ 941 /* free any machine hw params */
791 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free) 942 if (rtd->dai_link->ops && rtd->dai_link->ops->hw_free)
@@ -796,8 +947,11 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
796 platform->driver->ops->hw_free(substream); 947 platform->driver->ops->hw_free(substream);
797 948
798 /* now free hw params for the DAIs */ 949 /* now free hw params for the DAIs */
799 if (codec_dai->driver->ops && codec_dai->driver->ops->hw_free) 950 for (i = 0; i < rtd->num_codecs; i++) {
800 codec_dai->driver->ops->hw_free(substream, codec_dai); 951 codec_dai = rtd->codec_dais[i];
952 if (codec_dai->driver->ops && codec_dai->driver->ops->hw_free)
953 codec_dai->driver->ops->hw_free(substream, codec_dai);
954 }
801 955
802 if (cpu_dai->driver->ops && cpu_dai->driver->ops->hw_free) 956 if (cpu_dai->driver->ops && cpu_dai->driver->ops->hw_free)
803 cpu_dai->driver->ops->hw_free(substream, cpu_dai); 957 cpu_dai->driver->ops->hw_free(substream, cpu_dai);
@@ -811,13 +965,17 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
811 struct snd_soc_pcm_runtime *rtd = substream->private_data; 965 struct snd_soc_pcm_runtime *rtd = substream->private_data;
812 struct snd_soc_platform *platform = rtd->platform; 966 struct snd_soc_platform *platform = rtd->platform;
813 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 967 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
814 struct snd_soc_dai *codec_dai = rtd->codec_dai; 968 struct snd_soc_dai *codec_dai;
815 int ret; 969 int i, ret;
816 970
817 if (codec_dai->driver->ops && codec_dai->driver->ops->trigger) { 971 for (i = 0; i < rtd->num_codecs; i++) {
818 ret = codec_dai->driver->ops->trigger(substream, cmd, codec_dai); 972 codec_dai = rtd->codec_dais[i];
819 if (ret < 0) 973 if (codec_dai->driver->ops && codec_dai->driver->ops->trigger) {
820 return ret; 974 ret = codec_dai->driver->ops->trigger(substream,
975 cmd, codec_dai);
976 if (ret < 0)
977 return ret;
978 }
821 } 979 }
822 980
823 if (platform->driver->ops && platform->driver->ops->trigger) { 981 if (platform->driver->ops && platform->driver->ops->trigger) {
@@ -847,14 +1005,18 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
847 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1005 struct snd_soc_pcm_runtime *rtd = substream->private_data;
848 struct snd_soc_platform *platform = rtd->platform; 1006 struct snd_soc_platform *platform = rtd->platform;
849 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1007 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
850 struct snd_soc_dai *codec_dai = rtd->codec_dai; 1008 struct snd_soc_dai *codec_dai;
851 int ret; 1009 int i, ret;
852 1010
853 if (codec_dai->driver->ops && 1011 for (i = 0; i < rtd->num_codecs; i++) {
854 codec_dai->driver->ops->bespoke_trigger) { 1012 codec_dai = rtd->codec_dais[i];
855 ret = codec_dai->driver->ops->bespoke_trigger(substream, cmd, codec_dai); 1013 if (codec_dai->driver->ops &&
856 if (ret < 0) 1014 codec_dai->driver->ops->bespoke_trigger) {
857 return ret; 1015 ret = codec_dai->driver->ops->bespoke_trigger(substream,
1016 cmd, codec_dai);
1017 if (ret < 0)
1018 return ret;
1019 }
858 } 1020 }
859 1021
860 if (platform->driver->bespoke_trigger) { 1022 if (platform->driver->bespoke_trigger) {
@@ -880,10 +1042,12 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
880 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1042 struct snd_soc_pcm_runtime *rtd = substream->private_data;
881 struct snd_soc_platform *platform = rtd->platform; 1043 struct snd_soc_platform *platform = rtd->platform;
882 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1044 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
883 struct snd_soc_dai *codec_dai = rtd->codec_dai; 1045 struct snd_soc_dai *codec_dai;
884 struct snd_pcm_runtime *runtime = substream->runtime; 1046 struct snd_pcm_runtime *runtime = substream->runtime;
885 snd_pcm_uframes_t offset = 0; 1047 snd_pcm_uframes_t offset = 0;
886 snd_pcm_sframes_t delay = 0; 1048 snd_pcm_sframes_t delay = 0;
1049 snd_pcm_sframes_t codec_delay = 0;
1050 int i;
887 1051
888 if (platform->driver->ops && platform->driver->ops->pointer) 1052 if (platform->driver->ops && platform->driver->ops->pointer)
889 offset = platform->driver->ops->pointer(substream); 1053 offset = platform->driver->ops->pointer(substream);
@@ -891,11 +1055,21 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
891 if (cpu_dai->driver->ops && cpu_dai->driver->ops->delay) 1055 if (cpu_dai->driver->ops && cpu_dai->driver->ops->delay)
892 delay += cpu_dai->driver->ops->delay(substream, cpu_dai); 1056 delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
893 1057
894 if (codec_dai->driver->ops && codec_dai->driver->ops->delay) 1058 for (i = 0; i < rtd->num_codecs; i++) {
895 delay += codec_dai->driver->ops->delay(substream, codec_dai); 1059 codec_dai = rtd->codec_dais[i];
1060 if (codec_dai->driver->ops && codec_dai->driver->ops->delay)
1061 codec_delay = max(codec_delay,
1062 codec_dai->driver->ops->delay(substream,
1063 codec_dai));
1064 }
1065 delay += codec_delay;
896 1066
1067 /*
1068 * None of the existing platform drivers implement delay(), so
1069 * for now the codec_dai of first multicodec entry is used
1070 */
897 if (platform->driver->delay) 1071 if (platform->driver->delay)
898 delay += platform->driver->delay(substream, codec_dai); 1072 delay += platform->driver->delay(substream, rtd->codec_dais[0]);
899 1073
900 runtime->delay = delay; 1074 runtime->delay = delay;
901 1075
@@ -998,7 +1172,7 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
998 struct snd_soc_dapm_widget *widget, int stream) 1172 struct snd_soc_dapm_widget *widget, int stream)
999{ 1173{
1000 struct snd_soc_pcm_runtime *be; 1174 struct snd_soc_pcm_runtime *be;
1001 int i; 1175 int i, j;
1002 1176
1003 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 1177 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1004 for (i = 0; i < card->num_links; i++) { 1178 for (i = 0; i < card->num_links; i++) {
@@ -1007,9 +1181,14 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
1007 if (!be->dai_link->no_pcm) 1181 if (!be->dai_link->no_pcm)
1008 continue; 1182 continue;
1009 1183
1010 if (be->cpu_dai->playback_widget == widget || 1184 if (be->cpu_dai->playback_widget == widget)
1011 be->codec_dai->playback_widget == widget)
1012 return be; 1185 return be;
1186
1187 for (j = 0; j < be->num_codecs; j++) {
1188 struct snd_soc_dai *dai = be->codec_dais[j];
1189 if (dai->playback_widget == widget)
1190 return be;
1191 }
1013 } 1192 }
1014 } else { 1193 } else {
1015 1194
@@ -1019,9 +1198,14 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
1019 if (!be->dai_link->no_pcm) 1198 if (!be->dai_link->no_pcm)
1020 continue; 1199 continue;
1021 1200
1022 if (be->cpu_dai->capture_widget == widget || 1201 if (be->cpu_dai->capture_widget == widget)
1023 be->codec_dai->capture_widget == widget)
1024 return be; 1202 return be;
1203
1204 for (j = 0; j < be->num_codecs; j++) {
1205 struct snd_soc_dai *dai = be->codec_dais[j];
1206 if (dai->capture_widget == widget)
1207 return be;
1208 }
1025 } 1209 }
1026 } 1210 }
1027 1211
@@ -1084,6 +1268,7 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
1084 1268
1085 /* Destroy any old FE <--> BE connections */ 1269 /* Destroy any old FE <--> BE connections */
1086 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 1270 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1271 unsigned int i;
1087 1272
1088 /* is there a valid CPU DAI widget for this BE */ 1273 /* is there a valid CPU DAI widget for this BE */
1089 widget = dai_get_widget(dpcm->be->cpu_dai, stream); 1274 widget = dai_get_widget(dpcm->be->cpu_dai, stream);
@@ -1093,11 +1278,14 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream,
1093 continue; 1278 continue;
1094 1279
1095 /* is there a valid CODEC DAI widget for this BE */ 1280 /* is there a valid CODEC DAI widget for this BE */
1096 widget = dai_get_widget(dpcm->be->codec_dai, stream); 1281 for (i = 0; i < dpcm->be->num_codecs; i++) {
1282 struct snd_soc_dai *dai = dpcm->be->codec_dais[i];
1283 widget = dai_get_widget(dai, stream);
1097 1284
1098 /* prune the BE if it's no longer in our active list */ 1285 /* prune the BE if it's no longer in our active list */
1099 if (widget && widget_in_list(list, widget)) 1286 if (widget && widget_in_list(list, widget))
1100 continue; 1287 continue;
1288 }
1101 1289
1102 dev_dbg(fe->dev, "ASoC: pruning %s BE %s for %s\n", 1290 dev_dbg(fe->dev, "ASoC: pruning %s BE %s for %s\n",
1103 stream ? "capture" : "playback", 1291 stream ? "capture" : "playback",
@@ -2126,16 +2314,22 @@ int soc_dpcm_be_digital_mute(struct snd_soc_pcm_runtime *fe, int mute)
2126 list_for_each_entry(dpcm, clients, list_be) { 2314 list_for_each_entry(dpcm, clients, list_be) {
2127 2315
2128 struct snd_soc_pcm_runtime *be = dpcm->be; 2316 struct snd_soc_pcm_runtime *be = dpcm->be;
2129 struct snd_soc_dai *dai = be->codec_dai; 2317 int i;
2130 struct snd_soc_dai_driver *drv = dai->driver;
2131 2318
2132 if (be->dai_link->ignore_suspend) 2319 if (be->dai_link->ignore_suspend)
2133 continue; 2320 continue;
2134 2321
2135 dev_dbg(be->dev, "ASoC: BE digital mute %s\n", be->dai_link->name); 2322 for (i = 0; i < be->num_codecs; i++) {
2323 struct snd_soc_dai *dai = be->codec_dais[i];
2324 struct snd_soc_dai_driver *drv = dai->driver;
2325
2326 dev_dbg(be->dev, "ASoC: BE digital mute %s\n",
2327 be->dai_link->name);
2136 2328
2137 if (drv->ops && drv->ops->digital_mute && dai->playback_active) 2329 if (drv->ops && drv->ops->digital_mute &&
2138 drv->ops->digital_mute(dai, mute); 2330 dai->playback_active)
2331 drv->ops->digital_mute(dai, mute);
2332 }
2139 } 2333 }
2140 2334
2141 return 0; 2335 return 0;
@@ -2200,22 +2394,27 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
2200int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) 2394int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2201{ 2395{
2202 struct snd_soc_platform *platform = rtd->platform; 2396 struct snd_soc_platform *platform = rtd->platform;
2203 struct snd_soc_dai *codec_dai = rtd->codec_dai; 2397 struct snd_soc_dai *codec_dai;
2204 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 2398 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
2205 struct snd_pcm *pcm; 2399 struct snd_pcm *pcm;
2206 char new_name[64]; 2400 char new_name[64];
2207 int ret = 0, playback = 0, capture = 0; 2401 int ret = 0, playback = 0, capture = 0;
2402 int i;
2208 2403
2209 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { 2404 if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) {
2210 playback = rtd->dai_link->dpcm_playback; 2405 playback = rtd->dai_link->dpcm_playback;
2211 capture = rtd->dai_link->dpcm_capture; 2406 capture = rtd->dai_link->dpcm_capture;
2212 } else { 2407 } else {
2213 if (codec_dai->driver->playback.channels_min && 2408 for (i = 0; i < rtd->num_codecs; i++) {
2214 cpu_dai->driver->playback.channels_min) 2409 codec_dai = rtd->codec_dais[i];
2215 playback = 1; 2410 if (codec_dai->driver->playback.channels_min)
2216 if (codec_dai->driver->capture.channels_min && 2411 playback = 1;
2217 cpu_dai->driver->capture.channels_min) 2412 if (codec_dai->driver->capture.channels_min)
2218 capture = 1; 2413 capture = 1;
2414 }
2415
2416 capture = capture && cpu_dai->driver->capture.channels_min;
2417 playback = playback && cpu_dai->driver->playback.channels_min;
2219 } 2418 }
2220 2419
2221 if (rtd->dai_link->playback_only) { 2420 if (rtd->dai_link->playback_only) {
@@ -2241,7 +2440,9 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2241 rtd->dai_link->stream_name); 2440 rtd->dai_link->stream_name);
2242 else 2441 else
2243 snprintf(new_name, sizeof(new_name), "%s %s-%d", 2442 snprintf(new_name, sizeof(new_name), "%s %s-%d",
2244 rtd->dai_link->stream_name, codec_dai->name, num); 2443 rtd->dai_link->stream_name,
2444 (rtd->num_codecs > 1) ?
2445 "multicodec" : rtd->codec_dai->name, num);
2245 2446
2246 ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback, 2447 ret = snd_pcm_new(rtd->card->snd_card, new_name, num, playback,
2247 capture, &pcm); 2448 capture, &pcm);
@@ -2314,8 +2515,9 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2314 2515
2315 pcm->private_free = platform->driver->pcm_free; 2516 pcm->private_free = platform->driver->pcm_free;
2316out: 2517out:
2317 dev_info(rtd->card->dev, "%s <-> %s mapping ok\n", codec_dai->name, 2518 dev_info(rtd->card->dev, "%s <-> %s mapping ok\n",
2318 cpu_dai->name); 2519 (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,
2520 cpu_dai->name);
2319 return ret; 2521 return ret;
2320} 2522}
2321 2523