diff options
| author | Jyri Sarha <jsarha@ti.com> | 2015-04-23 09:16:04 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2015-04-30 15:47:16 -0400 |
| commit | 1f114f772ade64bca1c477322a18da8ed3bb8e6b (patch) | |
| tree | 3ed7996bee2104f1c1bfa6a59745f9b6e0edea7e | |
| parent | b787f68c36d49bb1d9236f403813641efa74a031 (diff) | |
ASoC: davinci-mcasp: Calculate BCLK using TDM slots and remove channels rule
The McASP driver currently always sends as many slots or channels to a
i2s-wire as there are configured tdm_slots (see mcasp_i2s_hw_param()).
Thus the BLCK rate does not depend on the amount of channels, just the
configure amount of tdm-slots.
Reported-by: Misael Lopez Cruz <misael.lopez@ti.com>
Signed-off-by: Jyri Sarha <jsarha@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
| -rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 82 |
1 files changed, 12 insertions, 70 deletions
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index bb4b78eada58..a01c6db6017b 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
| @@ -915,15 +915,12 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
| 915 | * the machine driver, we need to calculate the ratio. | 915 | * the machine driver, we need to calculate the ratio. |
| 916 | */ | 916 | */ |
| 917 | if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) { | 917 | if (mcasp->bclk_master && mcasp->bclk_div == 0 && mcasp->sysclk_freq) { |
| 918 | int channels = params_channels(params); | 918 | int slots = mcasp->tdm_slots; |
| 919 | int rate = params_rate(params); | 919 | int rate = params_rate(params); |
| 920 | int sbits = params_width(params); | 920 | int sbits = params_width(params); |
| 921 | int ppm, div; | 921 | int ppm, div; |
| 922 | 922 | ||
| 923 | if (channels > mcasp->tdm_slots) | 923 | div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*slots, |
| 924 | channels = mcasp->tdm_slots; | ||
| 925 | |||
| 926 | div = davinci_mcasp_calc_clk_div(mcasp, rate*sbits*channels, | ||
| 927 | &ppm); | 924 | &ppm); |
| 928 | if (ppm) | 925 | if (ppm) |
| 929 | dev_info(mcasp->dev, "Sample-rate is off by %d PPM\n", | 926 | dev_info(mcasp->dev, "Sample-rate is off by %d PPM\n", |
| @@ -1024,17 +1021,14 @@ static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params, | |||
| 1024 | struct snd_interval *ri = | 1021 | struct snd_interval *ri = |
| 1025 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 1022 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
| 1026 | int sbits = params_width(params); | 1023 | int sbits = params_width(params); |
| 1027 | int channels = params_channels(params); | 1024 | int slots = rd->mcasp->tdm_slots; |
| 1028 | unsigned int list[ARRAY_SIZE(davinci_mcasp_dai_rates)]; | 1025 | unsigned int list[ARRAY_SIZE(davinci_mcasp_dai_rates)]; |
| 1029 | int i, count = 0; | 1026 | int i, count = 0; |
| 1030 | 1027 | ||
| 1031 | if (channels > rd->mcasp->tdm_slots) | ||
| 1032 | channels = rd->mcasp->tdm_slots; | ||
| 1033 | |||
| 1034 | for (i = 0; i < ARRAY_SIZE(davinci_mcasp_dai_rates); i++) { | 1028 | for (i = 0; i < ARRAY_SIZE(davinci_mcasp_dai_rates); i++) { |
| 1035 | if (ri->min <= davinci_mcasp_dai_rates[i] && | 1029 | if (ri->min <= davinci_mcasp_dai_rates[i] && |
| 1036 | ri->max >= davinci_mcasp_dai_rates[i]) { | 1030 | ri->max >= davinci_mcasp_dai_rates[i]) { |
| 1037 | uint bclk_freq = sbits*channels* | 1031 | uint bclk_freq = sbits*slots* |
| 1038 | davinci_mcasp_dai_rates[i]; | 1032 | davinci_mcasp_dai_rates[i]; |
| 1039 | int ppm; | 1033 | int ppm; |
| 1040 | 1034 | ||
| @@ -1044,8 +1038,8 @@ static int davinci_mcasp_hw_rule_rate(struct snd_pcm_hw_params *params, | |||
| 1044 | } | 1038 | } |
| 1045 | } | 1039 | } |
| 1046 | dev_dbg(rd->mcasp->dev, | 1040 | dev_dbg(rd->mcasp->dev, |
| 1047 | "%d frequencies (%d-%d) for %d sbits and %d channels\n", | 1041 | "%d frequencies (%d-%d) for %d sbits and %d tdm slots\n", |
| 1048 | count, ri->min, ri->max, sbits, channels); | 1042 | count, ri->min, ri->max, sbits, slots); |
| 1049 | 1043 | ||
| 1050 | return snd_interval_list(hw_param_interval(params, rule->var), | 1044 | return snd_interval_list(hw_param_interval(params, rule->var), |
| 1051 | count, list, 0); | 1045 | count, list, 0); |
| @@ -1058,17 +1052,14 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params, | |||
| 1058 | struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); | 1052 | struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
| 1059 | struct snd_mask nfmt; | 1053 | struct snd_mask nfmt; |
| 1060 | int rate = params_rate(params); | 1054 | int rate = params_rate(params); |
| 1061 | int channels = params_channels(params); | 1055 | int slots = rd->mcasp->tdm_slots; |
| 1062 | int i, count = 0; | 1056 | int i, count = 0; |
| 1063 | 1057 | ||
| 1064 | snd_mask_none(&nfmt); | 1058 | snd_mask_none(&nfmt); |
| 1065 | 1059 | ||
| 1066 | if (channels > rd->mcasp->tdm_slots) | ||
| 1067 | channels = rd->mcasp->tdm_slots; | ||
| 1068 | |||
| 1069 | for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { | 1060 | for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) { |
| 1070 | if (snd_mask_test(fmt, i)) { | 1061 | if (snd_mask_test(fmt, i)) { |
| 1071 | uint bclk_freq = snd_pcm_format_width(i)*channels*rate; | 1062 | uint bclk_freq = snd_pcm_format_width(i)*slots*rate; |
| 1072 | int ppm; | 1063 | int ppm; |
| 1073 | 1064 | ||
| 1074 | davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm); | 1065 | davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm); |
| @@ -1079,51 +1070,12 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params, | |||
| 1079 | } | 1070 | } |
| 1080 | } | 1071 | } |
| 1081 | dev_dbg(rd->mcasp->dev, | 1072 | dev_dbg(rd->mcasp->dev, |
| 1082 | "%d possible sample format for %d Hz and %d channels\n", | 1073 | "%d possible sample format for %d Hz and %d tdm slots\n", |
| 1083 | count, rate, channels); | 1074 | count, rate, slots); |
| 1084 | 1075 | ||
| 1085 | return snd_mask_refine(fmt, &nfmt); | 1076 | return snd_mask_refine(fmt, &nfmt); |
| 1086 | } | 1077 | } |
| 1087 | 1078 | ||
| 1088 | static int davinci_mcasp_hw_rule_channels(struct snd_pcm_hw_params *params, | ||
| 1089 | struct snd_pcm_hw_rule *rule) | ||
| 1090 | { | ||
| 1091 | struct davinci_mcasp_ruledata *rd = rule->private; | ||
| 1092 | struct snd_interval *ci = | ||
| 1093 | hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | ||
| 1094 | int sbits = params_width(params); | ||
| 1095 | int rate = params_rate(params); | ||
| 1096 | int max_chan_per_wire = rd->mcasp->tdm_slots < ci->max ? | ||
| 1097 | rd->mcasp->tdm_slots : ci->max; | ||
| 1098 | unsigned int list[ci->max - ci->min + 1]; | ||
| 1099 | int c1, c, count = 0; | ||
| 1100 | |||
| 1101 | for (c1 = ci->min; c1 <= max_chan_per_wire; c1++) { | ||
| 1102 | uint bclk_freq = c1*sbits*rate; | ||
| 1103 | int ppm; | ||
| 1104 | |||
| 1105 | davinci_mcasp_calc_clk_div(rd->mcasp, bclk_freq, &ppm); | ||
| 1106 | if (abs(ppm) < DAVINCI_MAX_RATE_ERROR_PPM) { | ||
| 1107 | /* If we can use all tdm_slots, we can put any | ||
| 1108 | amount of channels to remaining wires as | ||
| 1109 | long as they fit in. */ | ||
| 1110 | if (c1 == rd->mcasp->tdm_slots) { | ||
| 1111 | for (c = c1; c <= rd->serializers*c1 && | ||
| 1112 | c <= ci->max; c++) | ||
| 1113 | list[count++] = c; | ||
| 1114 | } else { | ||
| 1115 | list[count++] = c1; | ||
| 1116 | } | ||
| 1117 | } | ||
| 1118 | } | ||
| 1119 | dev_dbg(rd->mcasp->dev, | ||
| 1120 | "%d possible channel counts (%d-%d) for %d Hz and %d sbits\n", | ||
| 1121 | count, ci->min, ci->max, rate, sbits); | ||
| 1122 | |||
| 1123 | return snd_interval_list(hw_param_interval(params, rule->var), | ||
| 1124 | count, list, 0); | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | static int davinci_mcasp_startup(struct snd_pcm_substream *substream, | 1079 | static int davinci_mcasp_startup(struct snd_pcm_substream *substream, |
| 1128 | struct snd_soc_dai *cpu_dai) | 1080 | struct snd_soc_dai *cpu_dai) |
| 1129 | { | 1081 | { |
| @@ -1180,24 +1132,14 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, | |||
| 1180 | SNDRV_PCM_HW_PARAM_RATE, | 1132 | SNDRV_PCM_HW_PARAM_RATE, |
| 1181 | davinci_mcasp_hw_rule_rate, | 1133 | davinci_mcasp_hw_rule_rate, |
| 1182 | ruledata, | 1134 | ruledata, |
| 1183 | SNDRV_PCM_HW_PARAM_FORMAT, | 1135 | SNDRV_PCM_HW_PARAM_FORMAT, -1); |
| 1184 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
| 1185 | if (ret) | 1136 | if (ret) |
| 1186 | return ret; | 1137 | return ret; |
| 1187 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, | 1138 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, |
| 1188 | SNDRV_PCM_HW_PARAM_FORMAT, | 1139 | SNDRV_PCM_HW_PARAM_FORMAT, |
| 1189 | davinci_mcasp_hw_rule_format, | 1140 | davinci_mcasp_hw_rule_format, |
| 1190 | ruledata, | 1141 | ruledata, |
| 1191 | SNDRV_PCM_HW_PARAM_RATE, | 1142 | SNDRV_PCM_HW_PARAM_RATE, -1); |
| 1192 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | ||
| 1193 | if (ret) | ||
| 1194 | return ret; | ||
| 1195 | ret = snd_pcm_hw_rule_add(substream->runtime, 0, | ||
| 1196 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
| 1197 | davinci_mcasp_hw_rule_channels, | ||
| 1198 | ruledata, | ||
| 1199 | SNDRV_PCM_HW_PARAM_RATE, | ||
| 1200 | SNDRV_PCM_HW_PARAM_FORMAT, -1); | ||
| 1201 | if (ret) | 1143 | if (ret) |
| 1202 | return ret; | 1144 | return ret; |
| 1203 | } | 1145 | } |
