asoc: wm8903: Fix clock functions
ScottPeterson [Wed, 18 Jan 2012 00:51:20 +0000 (16:51 -0800)]
Clock function for non-integral of sample
rate clocks does not work correctly and
generates incorrect sample rate.

Signed-off-by: ScottPeterson <speterson@nvidia.com>

Reviewed-on: http://git-master/r/75792

Change-Id: I39977c9e2b647d4eabc8d9209c2d05665f708ab0
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/77752
Reviewed-by: Automatic_Commit_Validation_User

sound/soc/codecs/wm8903.c

index a5193a9..0218d6c 100644 (file)
@@ -1268,9 +1268,9 @@ static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
                aif1 |= 0x2;
                break;
        case SND_SOC_DAIFMT_RIGHT_J:
-               aif1 |= 0x1;
                break;
        case SND_SOC_DAIFMT_LEFT_J:
+               aif1 |= 0x1;
                break;
        default:
                return -EINVAL;
@@ -1457,6 +1457,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
        int fs = params_rate(params);
        int bclk;
        int bclk_div;
+       int real_bclk_div;
        int i;
        int dsp_config;
        int clk_config;
@@ -1561,27 +1562,22 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
         * higher than the target (we need to ensure that there enough
         * BCLKs to clock out the samples).
         */
-       bclk_div = 0;
-       best_val = ((clk_sys * 10) / bclk_divs[0].ratio) - bclk;
-       i = 1;
-       while (i < ARRAY_SIZE(bclk_divs)) {
-               cur_val = ((clk_sys * 10) / bclk_divs[i].ratio) - bclk;
-               if (cur_val < 0) /* BCLK table is sorted */
-                       break;
-               bclk_div = i;
-               best_val = cur_val;
-               i++;
-       }
 
        aif2 &= ~WM8903_BCLK_DIV_MASK;
        aif3 &= ~WM8903_LRCLK_RATE_MASK;
 
-       dev_dbg(codec->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n",
-               bclk_divs[bclk_div].ratio / 10, bclk,
-               (clk_sys * 10) / bclk_divs[bclk_div].ratio);
-
-       aif2 |= bclk_divs[bclk_div].div;
-       aif3 |= bclk / fs;
+       bclk_div = real_bclk_div = 0;
+       cur_val = clk_sys;
+       best_val = clk_sys;
+       while(!(best_val % fs) &&
+                       (cur_val >= bclk)){
+               real_bclk_div = bclk_div;
+               bclk_div++;
+               cur_val = best_val;
+               best_val /= 2;
+       }
+       aif2 |= (real_bclk_div ? 1<<real_bclk_div : 0);
+       aif3 |= cur_val / fs;
 
        wm8903->fs = params_rate(params);
        wm8903_set_deemph(codec);