ASoC: wm8523: Set bclk ratio for master mode
authorJulian Scheel <julian@jusst.de>
Fri, 12 Jun 2015 13:57:32 +0000 (15:57 +0200)
committerMark Brown <broonie@kernel.org>
Fri, 12 Jun 2015 16:16:57 +0000 (17:16 +0100)
When running in master mode the bclk divider must be configured to generate a
sane bitclock. Pick the smallest fs multiplicator, which can hold all
transmitted bits.

Signed-off-by: Julian Scheel <julian@jusst.de>
Acked-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/wm8523.c

index b1cc94f5fc4b253282a71d167cbb1815861d99d1..f9dffd2d5eea6ee2c7134770ddd548d07d4c53f3 100644 (file)
@@ -113,6 +113,15 @@ static struct {
        { 7, 1152 },
 };
 
+static struct {
+       int value;
+       int ratio;
+} bclk_ratios[WM8523_NUM_RATES] = {
+       { 2, 32 },
+       { 3, 64 },
+       { 4, 128 },
+};
+
 static int wm8523_startup(struct snd_pcm_substream *substream,
                          struct snd_soc_dai *dai)
 {
@@ -162,6 +171,23 @@ static int wm8523_hw_params(struct snd_pcm_substream *substream,
        aifctrl2 &= ~WM8523_SR_MASK;
        aifctrl2 |= lrclk_ratios[i].value;
 
+       if (aifctrl1 & WM8523_AIF_MSTR) {
+               /* Find a fs->bclk ratio */
+               for (i = 0; i < ARRAY_SIZE(bclk_ratios); i++)
+                       if (params_width(params) * 2 <= bclk_ratios[i].ratio)
+                               break;
+
+               if (i == ARRAY_SIZE(bclk_ratios)) {
+                       dev_err(codec->dev,
+                               "No matching BCLK/fs ratio for word length %d\n",
+                               params_width(params));
+                       return -EINVAL;
+               }
+
+               aifctrl2 &= ~WM8523_BCLKDIV_MASK;
+               aifctrl2 |= bclk_ratios[i].value << WM8523_BCLKDIV_SHIFT;
+       }
+
        aifctrl1 &= ~WM8523_WL_MASK;
        switch (params_width(params)) {
        case 16: