diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2015-05-11 22:03:33 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-05-22 08:38:40 -0400 |
commit | b073ed4e21268da59c40a4fc5d56e3af808ecc4d (patch) | |
tree | 8d7a781e34633e69385409bb28567d404e688a98 /sound/soc/soc-pcm.c | |
parent | 2dc0f16b83b43fd1f86a2358d46f46488230c6c8 (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.c | 47 |
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 | ||
1487 | static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, | 1487 | static 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 | ||
1502 | static 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 | |||
1501 | static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) | 1537 | static 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 | ||
1514 | static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd); | 1551 | static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd); |