aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2015-05-22 09:12:56 -0400
committerMark Brown <broonie@kernel.org>2015-05-22 09:12:56 -0400
commit96a5d3f017dbbb3947f701984f729249fc0f49a8 (patch)
tree5ba7ccebf89a24c89394a207ad2ce6fe06e7ff6c
parent5626ad0866657c4758958040589b395d2a58816d (diff)
parentb073ed4e21268da59c40a4fc5d56e3af808ecc4d (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.h39
-rw-r--r--sound/soc/soc-pcm.c47
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
992struct snd_soc_codec_conf { 995struct 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
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);