aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/davinci/davinci-mcasp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/davinci/davinci-mcasp.c')
-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,