diff options
| -rw-r--r-- | include/sound/soc.h | 3 | ||||
| -rw-r--r-- | sound/soc/soc-pcm.c | 47 |
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 | ||
| 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); |
