aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/davinci
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2014-11-10 05:32:16 -0500
committerMark Brown <broonie@kernel.org>2014-11-10 10:00:01 -0500
commit11277833ce8018ddd18925d2f85037bf02dcba63 (patch)
treef8bf476c1d629c69256b2cfd17f74f20c7dc9df6 /sound/soc/davinci
parent1a5923da4e2e6997f03545a2b88f2cd2dea1a5c2 (diff)
ASoC: davinci-mcasp: Place constraint on number of channels
In IIS (I2S, TDM, etc) mode the maximum number of allowed channels for either direction can be: number of serializers for the direction * tdm_slots. This constraint applicable for the first stream, while consequent stream should not have more channels then the first stream. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/davinci')
-rw-r--r--sound/soc/davinci/davinci-mcasp.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 10c264738a0b..10ae75e19d99 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -90,6 +90,9 @@ struct davinci_mcasp {
90 90
91 bool dat_port; 91 bool dat_port;
92 92
93 /* Used for comstraint setting on the second stream */
94 u32 channels;
95
93#ifdef CONFIG_PM_SLEEP 96#ifdef CONFIG_PM_SLEEP
94 struct davinci_mcasp_context context; 97 struct davinci_mcasp_context context;
95#endif 98#endif
@@ -811,6 +814,9 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
811 814
812 davinci_config_channel_size(mcasp, word_length); 815 davinci_config_channel_size(mcasp, word_length);
813 816
817 if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE)
818 mcasp->channels = channels;
819
814 return 0; 820 return 0;
815} 821}
816 822
@@ -839,7 +845,61 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
839 return ret; 845 return ret;
840} 846}
841 847
848static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
849 struct snd_soc_dai *cpu_dai)
850{
851 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
852 u32 max_channels = 0;
853 int i, dir;
854
855 if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
856 return 0;
857
858 /*
859 * Limit the maximum allowed channels for the first stream:
860 * number of serializers for the direction * tdm slots per serializer
861 */
862 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
863 dir = TX_MODE;
864 else
865 dir = RX_MODE;
866
867 for (i = 0; i < mcasp->num_serializer; i++) {
868 if (mcasp->serial_dir[i] == dir)
869 max_channels++;
870 }
871 max_channels *= mcasp->tdm_slots;
872 /*
873 * If the already active stream has less channels than the calculated
874 * limnit based on the seirializers * tdm_slots, we need to use that as
875 * a constraint for the second stream.
876 * Otherwise (first stream or less allowed channels) we use the
877 * calculated constraint.
878 */
879 if (mcasp->channels && mcasp->channels < max_channels)
880 max_channels = mcasp->channels;
881
882 snd_pcm_hw_constraint_minmax(substream->runtime,
883 SNDRV_PCM_HW_PARAM_CHANNELS,
884 2, max_channels);
885 return 0;
886}
887
888static void davinci_mcasp_shutdown(struct snd_pcm_substream *substream,
889 struct snd_soc_dai *cpu_dai)
890{
891 struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai);
892
893 if (mcasp->op_mode == DAVINCI_MCASP_DIT_MODE)
894 return;
895
896 if (!cpu_dai->active)
897 mcasp->channels = 0;
898}
899
842static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { 900static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
901 .startup = davinci_mcasp_startup,
902 .shutdown = davinci_mcasp_shutdown,
843 .trigger = davinci_mcasp_trigger, 903 .trigger = davinci_mcasp_trigger,
844 .hw_params = davinci_mcasp_hw_params, 904 .hw_params = davinci_mcasp_hw_params,
845 .set_fmt = davinci_mcasp_set_dai_fmt, 905 .set_fmt = davinci_mcasp_set_dai_fmt,