aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc.h3
-rw-r--r--sound/soc/soc-pcm.c47
2 files changed, 45 insertions, 5 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 38757fe7a3d8..cf63ac1c8968 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -985,6 +985,9 @@ struct snd_soc_dai_link {
985 unsigned int dpcm_capture:1; 985 unsigned int dpcm_capture:1;
986 unsigned int dpcm_playback:1; 986 unsigned int dpcm_playback:1;
987 987
988 /* DPCM used FE & BE merged format */
989 unsigned int dpcm_merged_format:1;
990
988 /* pmdown_time is ignored at stop */ 991 /* pmdown_time is ignored at stop */
989 unsigned int ignore_pmdown_time:1; 992 unsigned int ignore_pmdown_time:1;
990}; 993};
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 35fe58f4fa86..256b9c91aa94 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1485,30 +1485,67 @@ unwind:
1485} 1485}
1486 1486
1487static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, 1487static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime,
1488 struct snd_soc_pcm_stream *stream) 1488 struct snd_soc_pcm_stream *stream,
1489 u64 formats)
1489{ 1490{
1490 runtime->hw.rate_min = stream->rate_min; 1491 runtime->hw.rate_min = stream->rate_min;
1491 runtime->hw.rate_max = stream->rate_max; 1492 runtime->hw.rate_max = stream->rate_max;
1492 runtime->hw.channels_min = stream->channels_min; 1493 runtime->hw.channels_min = stream->channels_min;
1493 runtime->hw.channels_max = stream->channels_max; 1494 runtime->hw.channels_max = stream->channels_max;
1494 if (runtime->hw.formats) 1495 if (runtime->hw.formats)
1495 runtime->hw.formats &= stream->formats; 1496 runtime->hw.formats &= formats & stream->formats;
1496 else 1497 else
1497 runtime->hw.formats = stream->formats; 1498 runtime->hw.formats = formats & stream->formats;
1498 runtime->hw.rates = stream->rates; 1499 runtime->hw.rates = stream->rates;
1499} 1500}
1500 1501
1502static u64 dpcm_runtime_base_format(struct snd_pcm_substream *substream)
1503{
1504 struct snd_soc_pcm_runtime *fe = substream->private_data;
1505 struct snd_soc_dpcm *dpcm;
1506 u64 formats = ULLONG_MAX;
1507 int stream = substream->stream;
1508
1509 if (!fe->dai_link->dpcm_merged_format)
1510 return formats;
1511
1512 /*
1513 * It returns merged BE codec format
1514 * if FE want to use it (= dpcm_merged_format)
1515 */
1516
1517 list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
1518 struct snd_soc_pcm_runtime *be = dpcm->be;
1519 struct snd_soc_dai_driver *codec_dai_drv;
1520 struct snd_soc_pcm_stream *codec_stream;
1521 int i;
1522
1523 for (i = 0; i < be->num_codecs; i++) {
1524 codec_dai_drv = be->codec_dais[i]->driver;
1525 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
1526 codec_stream = &codec_dai_drv->playback;
1527 else
1528 codec_stream = &codec_dai_drv->capture;
1529
1530 formats &= codec_stream->formats;
1531 }
1532 }
1533
1534 return formats;
1535}
1536
1501static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) 1537static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream)
1502{ 1538{
1503 struct snd_pcm_runtime *runtime = substream->runtime; 1539 struct snd_pcm_runtime *runtime = substream->runtime;
1504 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1540 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1505 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1541 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1506 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver; 1542 struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver;
1543 u64 format = dpcm_runtime_base_format(substream);
1507 1544
1508 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1545 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1509 dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback); 1546 dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback, format);
1510 else 1547 else
1511 dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture); 1548 dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture, format);
1512} 1549}
1513 1550
1514static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd); 1551static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd);