aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMaxime Ripard <maxime.ripard@bootlin.com>2019-08-19 15:25:14 -0400
committerMark Brown <broonie@kernel.org>2019-08-20 13:23:42 -0400
commit7df8f9a20196072162d9dc8fe99943f2d35f23d5 (patch)
tree9a519f73472c28b43eb09c6b117650f3a366e723 /sound
parenta49d24e7d8d4fd4edf59e6373983e0bf4a2cca15 (diff)
ASoC: sun4i-i2s: Don't use the oversample to calculate BCLK
The BCLK divider should be calculated using the parameters that actually make the BCLK rate: the number of channels, the sampling rate and the sample width. We've been using the oversample_rate previously because in the former SoCs, the BCLK's parent is MCLK, which in turn is being used to generate the oversample rate, so we end up with something like this: oversample = mclk_rate / sampling_rate bclk_div = oversample / word_size / channels So, bclk_div = mclk_rate / sampling_rate / word_size / channels. And this is actually better, since the oversampling ratio only plays a role because the MCLK is its parent, not because of what BCLK is supposed to be. Furthermore, that assumption of MCLK being the parent has been broken on newer SoCs, so let's use the proper formula, and have the parent rate as an argument. Fixes: 7d2993811a1e ("ASoC: sun4i-i2s: Add support for H3") Fixes: 21faaea1343f ("ASoC: sun4i-i2s: Add support for A83T") Fixes: 66ecce332538 ("ASoC: sun4i-i2s: Add compatibility with A64 codec I2S") Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com> Link: https://lore.kernel.org/r/c3595e3a9788c2ef2dcc30aa3c8c4953bb5cc249.1566242458.git-series.maxime.ripard@bootlin.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/sunxi/sun4i-i2s.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 70608fa30bf2..d879db581073 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -222,10 +222,11 @@ static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = {
222}; 222};
223 223
224static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s, 224static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s,
225 unsigned int oversample_rate, 225 unsigned long parent_rate,
226 unsigned int sampling_rate,
226 unsigned int word_size) 227 unsigned int word_size)
227{ 228{
228 int div = oversample_rate / word_size / 2; 229 int div = parent_rate / sampling_rate / word_size / 2;
229 int i; 230 int i;
230 231
231 for (i = 0; i < ARRAY_SIZE(sun4i_i2s_bclk_div); i++) { 232 for (i = 0; i < ARRAY_SIZE(sun4i_i2s_bclk_div); i++) {
@@ -315,8 +316,8 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
315 return -EINVAL; 316 return -EINVAL;
316 } 317 }
317 318
318 bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate, 319 bclk_div = sun4i_i2s_get_bclk_div(i2s, i2s->mclk_freq,
319 word_size); 320 rate, word_size);
320 if (bclk_div < 0) { 321 if (bclk_div < 0) {
321 dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div); 322 dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div);
322 return -EINVAL; 323 return -EINVAL;