ASoC: tlv320aic31xx: Fix 24bit samples with I2S format and 12MHz mclk
authorJyri Sarha <jsarha@ti.com>
Wed, 3 Sep 2014 12:52:33 +0000 (15:52 +0300)
committerMark Brown <broonie@kernel.org>
Wed, 3 Sep 2014 14:23:56 +0000 (15:23 +0100)
I2S format requires bitclock to have an exact amount of cycles in a
frame for audio to work cleanly. With dsp formats that is not so
important.

Updates aic31xx_setup_pll() to look for a line in aic31xx_divs table
that produces the best match for the bitclock and adds lines to
aic31xx_divs for 12MHz mclk and 24bit samples.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
Tested-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/tlv320aic31xx.c

index 0f64c7890eed65a6efaaf1cea2bdf4b888950ca7..aea9e1ff9126592b91c70d29195725b0b2e183bd 100644 (file)
@@ -189,46 +189,57 @@ static const struct aic31xx_rate_divs aic31xx_divs[] = {
        /* mclk      rate  pll: p  j     d     dosr ndac mdac  aors nadc madc */
        /* 8k rate */
        {12000000,   8000,      1, 8, 1920,     128,  48,  2,   128,  48,  2},
+       {12000000,   8000,      1, 8, 1920,     128,  32,  3,   128,  32,  3},
        {24000000,   8000,      2, 8, 1920,     128,  48,  2,   128,  48,  2},
        {25000000,   8000,      2, 7, 8643,     128,  48,  2,   128,  48,  2},
        /* 11.025k rate */
        {12000000,  11025,      1, 7, 5264,     128,  32,  2,   128,  32,  2},
+       {12000000,  11025,      1, 8, 4672,     128,  24,  3,   128,  24,  3},
        {24000000,  11025,      2, 7, 5264,     128,  32,  2,   128,  32,  2},
        {25000000,  11025,      2, 7, 2253,     128,  32,  2,   128,  32,  2},
        /* 16k rate */
        {12000000,  16000,      1, 8, 1920,     128,  24,  2,   128,  24,  2},
+       {12000000,  16000,      1, 8, 1920,     128,  16,  3,   128,  16,  3},
        {24000000,  16000,      2, 8, 1920,     128,  24,  2,   128,  24,  2},
        {25000000,  16000,      2, 7, 8643,     128,  24,  2,   128,  24,  2},
        /* 22.05k rate */
        {12000000,  22050,      1, 7, 5264,     128,  16,  2,   128,  16,  2},
+       {12000000,  22050,      1, 8, 4672,     128,  12,  3,   128,  12,  3},
        {24000000,  22050,      2, 7, 5264,     128,  16,  2,   128,  16,  2},
        {25000000,  22050,      2, 7, 2253,     128,  16,  2,   128,  16,  2},
        /* 32k rate */
        {12000000,  32000,      1, 8, 1920,     128,  12,  2,   128,  12,  2},
+       {12000000,  32000,      1, 8, 1920,     128,   8,  3,   128,   8,  3},
        {24000000,  32000,      2, 8, 1920,     128,  12,  2,   128,  12,  2},
        {25000000,  32000,      2, 7, 8643,     128,  12,  2,   128,  12,  2},
        /* 44.1k rate */
        {12000000,  44100,      1, 7, 5264,     128,   8,  2,   128,   8,  2},
+       {12000000,  44100,      1, 8, 4672,     128,   6,  3,   128,   6,  3},
        {24000000,  44100,      2, 7, 5264,     128,   8,  2,   128,   8,  2},
        {25000000,  44100,      2, 7, 2253,     128,   8,  2,   128,   8,  2},
        /* 48k rate */
        {12000000,  48000,      1, 8, 1920,     128,   8,  2,   128,   8,  2},
+       {12000000,  48000,      1, 7, 6800,      96,   5,  4,    96,   5,  4},
        {24000000,  48000,      2, 8, 1920,     128,   8,  2,   128,   8,  2},
        {25000000,  48000,      2, 7, 8643,     128,   8,  2,   128,   8,  2},
        /* 88.2k rate */
        {12000000,  88200,      1, 7, 5264,      64,   8,  2,    64,   8,  2},
+       {12000000,  88200,      1, 8, 4672,      64,   6,  3,    64,   6,  3},
        {24000000,  88200,      2, 7, 5264,      64,   8,  2,    64,   8,  2},
        {25000000,  88200,      2, 7, 2253,      64,   8,  2,    64,   8,  2},
        /* 96k rate */
        {12000000,  96000,      1, 8, 1920,      64,   8,  2,    64,   8,  2},
+       {12000000,  96000,      1, 7, 6800,      48,   5,  4,    48,   5,  4},
        {24000000,  96000,      2, 8, 1920,      64,   8,  2,    64,   8,  2},
        {25000000,  96000,      2, 7, 8643,      64,   8,  2,    64,   8,  2},
        /* 176.4k rate */
        {12000000, 176400,      1, 7, 5264,      32,   8,  2,    32,   8,  2},
+       {12000000, 176400,      1, 8, 4672,      32,   6,  3,    32,   6,  3},
        {24000000, 176400,      2, 7, 5264,      32,   8,  2,    32,   8,  2},
        {25000000, 176400,      2, 7, 2253,      32,   8,  2,    32,   8,  2},
        /* 192k rate */
        {12000000, 192000,      1, 8, 1920,      32,   8,  2,    32,   8,  2},
+       {12000000, 192000,      1, 7, 6800,      24,   5,  4,    24,   5,  4},
        {24000000, 192000,      2, 8, 1920,      32,   8,  2,    32,   8,  2},
        {25000000, 192000,      2, 7, 8643,      32,   8,  2,    32,   8,  2},
 };
@@ -680,7 +691,9 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
                             struct snd_pcm_hw_params *params)
 {
        struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+       int bclk_score = snd_soc_params_to_frame_size(params);
        int bclk_n = 0;
+       int match = -1;
        int i;
 
        /* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */
@@ -691,15 +704,37 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
 
        for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) {
                if (aic31xx_divs[i].rate == params_rate(params) &&
-                   aic31xx_divs[i].mclk == aic31xx->sysclk)
-                       break;
+                   aic31xx_divs[i].mclk == aic31xx->sysclk) {
+                       int s = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) %
+                               snd_soc_params_to_frame_size(params);
+                       int bn = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) /
+                               snd_soc_params_to_frame_size(params);
+                       if (s < bclk_score && bn > 0) {
+                               match = i;
+                               bclk_n = bn;
+                               bclk_score = s;
+                       }
+               }
        }
 
-       if (i == ARRAY_SIZE(aic31xx_divs)) {
-               dev_err(codec->dev, "%s: Sampling rate %u not supported\n",
+       if (match == -1) {
+               dev_err(codec->dev,
+                       "%s: Sample rate (%u) and format not supported\n",
                        __func__, params_rate(params));
+               /* See bellow for details how fix this. */
                return -EINVAL;
        }
+       if (bclk_score != 0) {
+               dev_warn(codec->dev, "Can not produce exact bitclock");
+               /* This is fine if using dsp format, but if using i2s
+                  there may be trouble. To fix the issue edit the
+                  aic31xx_divs table for your mclk and sample
+                  rate. Details can be found from:
+                  http://www.ti.com/lit/ds/symlink/tlv320aic3100.pdf
+                  Section: 5.6 CLOCK Generation and PLL
+               */
+       }
+       i = match;
 
        /* PLL configuration */
        snd_soc_update_bits(codec, AIC31XX_PLLPR, AIC31XX_PLL_MASK,
@@ -729,14 +764,6 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
        snd_soc_write(codec, AIC31XX_AOSR, aic31xx_divs[i].aosr);
 
        /* Bit clock divider configuration. */
-       bclk_n = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac)
-               / snd_soc_params_to_frame_size(params);
-       if (bclk_n == 0) {
-               dev_err(codec->dev, "%s: Not enough BLCK bandwidth\n",
-                       __func__);
-               return -EINVAL;
-       }
-
        snd_soc_update_bits(codec, AIC31XX_BCLKN,
                            AIC31XX_PLL_MASK, bclk_n);