diff options
author | Mark Brown <broonie@kernel.org> | 2015-05-22 09:12:56 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-05-22 09:12:56 -0400 |
commit | 96a5d3f017dbbb3947f701984f729249fc0f49a8 (patch) | |
tree | 5ba7ccebf89a24c89394a207ad2ce6fe06e7ff6c | |
parent | 5626ad0866657c4758958040589b395d2a58816d (diff) | |
parent | b073ed4e21268da59c40a4fc5d56e3af808ecc4d (diff) |
Merge branch 'topic/dpcm' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-rcar
-rw-r--r-- | include/sound/soc.h | 39 | ||||
-rw-r--r-- | sound/soc/soc-pcm.c | 47 |
2 files changed, 63 insertions, 23 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index fcb312b3f258..cf63ac1c8968 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -949,6 +949,24 @@ struct snd_soc_dai_link { | |||
949 | 949 | ||
950 | enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */ | 950 | enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */ |
951 | 951 | ||
952 | /* codec/machine specific init - e.g. add machine controls */ | ||
953 | int (*init)(struct snd_soc_pcm_runtime *rtd); | ||
954 | |||
955 | /* optional hw_params re-writing for BE and FE sync */ | ||
956 | int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd, | ||
957 | struct snd_pcm_hw_params *params); | ||
958 | |||
959 | /* machine stream operations */ | ||
960 | const struct snd_soc_ops *ops; | ||
961 | const struct snd_soc_compr_ops *compr_ops; | ||
962 | |||
963 | /* For unidirectional dai links */ | ||
964 | bool playback_only; | ||
965 | bool capture_only; | ||
966 | |||
967 | /* Mark this pcm with non atomic ops */ | ||
968 | bool nonatomic; | ||
969 | |||
952 | /* Keep DAI active over suspend */ | 970 | /* Keep DAI active over suspend */ |
953 | unsigned int ignore_suspend:1; | 971 | unsigned int ignore_suspend:1; |
954 | 972 | ||
@@ -957,9 +975,6 @@ struct snd_soc_dai_link { | |||
957 | unsigned int symmetric_channels:1; | 975 | unsigned int symmetric_channels:1; |
958 | unsigned int symmetric_samplebits:1; | 976 | unsigned int symmetric_samplebits:1; |
959 | 977 | ||
960 | /* Mark this pcm with non atomic ops */ | ||
961 | bool nonatomic; | ||
962 | |||
963 | /* Do not create a PCM for this DAI link (Backend link) */ | 978 | /* Do not create a PCM for this DAI link (Backend link) */ |
964 | unsigned int no_pcm:1; | 979 | unsigned int no_pcm:1; |
965 | 980 | ||
@@ -970,23 +985,11 @@ struct snd_soc_dai_link { | |||
970 | unsigned int dpcm_capture:1; | 985 | unsigned int dpcm_capture:1; |
971 | unsigned int dpcm_playback:1; | 986 | unsigned int dpcm_playback:1; |
972 | 987 | ||
988 | /* DPCM used FE & BE merged format */ | ||
989 | unsigned int dpcm_merged_format:1; | ||
990 | |||
973 | /* pmdown_time is ignored at stop */ | 991 | /* pmdown_time is ignored at stop */ |
974 | unsigned int ignore_pmdown_time:1; | 992 | unsigned int ignore_pmdown_time:1; |
975 | |||
976 | /* codec/machine specific init - e.g. add machine controls */ | ||
977 | int (*init)(struct snd_soc_pcm_runtime *rtd); | ||
978 | |||
979 | /* optional hw_params re-writing for BE and FE sync */ | ||
980 | int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd, | ||
981 | struct snd_pcm_hw_params *params); | ||
982 | |||
983 | /* machine stream operations */ | ||
984 | const struct snd_soc_ops *ops; | ||
985 | const struct snd_soc_compr_ops *compr_ops; | ||
986 | |||
987 | /* For unidirectional dai links */ | ||
988 | bool playback_only; | ||
989 | bool capture_only; | ||
990 | }; | 993 | }; |
991 | 994 | ||
992 | struct snd_soc_codec_conf { | 995 | struct snd_soc_codec_conf { |
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); |