diff options
author | Peter Ujfalusi <peter.ujfalusi@ti.com> | 2014-11-10 05:32:16 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2014-11-10 10:00:01 -0500 |
commit | 11277833ce8018ddd18925d2f85037bf02dcba63 (patch) | |
tree | f8bf476c1d629c69256b2cfd17f74f20c7dc9df6 /sound/soc/davinci | |
parent | 1a5923da4e2e6997f03545a2b88f2cd2dea1a5c2 (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.c | 60 |
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 | ||
848 | static 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 | |||
888 | static 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 | |||
842 | static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { | 900 | static 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, |