aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-pcm.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2015-05-11 22:03:33 -0400
committerMark Brown <broonie@kernel.org>2015-05-22 08:38:40 -0400
commitb073ed4e21268da59c40a4fc5d56e3af808ecc4d (patch)
tree8d7a781e34633e69385409bb28567d404e688a98 /sound/soc/soc-pcm.c
parent2dc0f16b83b43fd1f86a2358d46f46488230c6c8 (diff)
ASoC: soc-pcm: DPCM cares BE format
Current DPCM is caring only FE format. but it will be no sound if FE/BE was below style, and user selects S24_LE format. FE: S16_LE/S24_LE BE: S16_LE DPCM can rewrite the format, so basically we don't want to constrain with the BE constraints. But sometimes it will be trouble. This patch adds new .dpcm_merged_format on struct snd_soc_dai_link. DPCM will use FE / BE merged format if .struct snd_soc_dai_link has it. We can have other .dpcm_merged_xxx in the future .dpcm_merged_foramt .dpcm_merged_rate .dpcm_merged_chan Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Tested-by: Keita Kobayashi <keita.kobayashi.ym@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/soc-pcm.c')
-rw-r--r--sound/soc/soc-pcm.c47
1 files changed, 42 insertions, 5 deletions
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);