MLK-14851: ASoC: wm8962: fix clock issue for S20_3LE
authorShengjiu Wang <shengjiu.wang@freescale.com>
Mon, 8 May 2017 07:15:44 +0000 (15:15 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:22:13 +0000 (15:22 -0500)
There is error log "wm8962 3-001a: Unsupported BCLK ratio 6"
When the bitstream's format is S20_3LE.
The reason is that the pll output is samplerate*256, which
can't divide to clock samplerate*20*2. So in this patch change
the pll output to samplerate*384, and use the physical_width
for S20_3LE to calculate the bclk.

Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
sound/soc/codecs/wm8962.c
sound/soc/fsl/imx-wm8962.c

index 79a78d8..47bb93e 100644 (file)
@@ -2,6 +2,7 @@
  * wm8962.c  --  WM8962 ALSA SoC Audio driver
  *
  * Copyright 2010-2 Wolfson Microelectronics plc
+ * Copyright 2017 NXP
  *
  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  *
@@ -2561,11 +2562,17 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_codec *codec = dai->codec;
        struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
+       snd_pcm_format_t sample_format = params_format(params);
        int i;
        int aif0 = 0;
        int adctl3 = 0;
 
-       wm8962->bclk = snd_soc_params_to_bclk(params);
+       if (sample_format == SNDRV_PCM_FORMAT_S20_3LE)
+               wm8962->bclk = params_rate(params) *
+                               params_channels(params) *
+                               params_physical_width(params);
+       else
+               wm8962->bclk = snd_soc_params_to_bclk(params);
        if (params_channels(params) == 1)
                wm8962->bclk *= 2;
 
index 9bf3d1b..2cbb35a 100644 (file)
@@ -4,6 +4,7 @@
  * Based on imx-sgtl5000.c
  * Copyright (C) 2012 Freescale Semiconductor, Inc.
  * Copyright (C) 2012 Linaro Ltd.
+ * Copyright 2017 NXP
  *
  * The code contained herein is licensed under the GNU General Public
  * License. You may obtain a copy of the GNU General Public License
@@ -263,7 +264,8 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
        switch (level) {
        case SND_SOC_BIAS_PREPARE:
                if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
-                       if (sample_format == SNDRV_PCM_FORMAT_S24_LE)
+                       if (sample_format == SNDRV_PCM_FORMAT_S24_LE
+                               || sample_format == SNDRV_PCM_FORMAT_S20_3LE)
                                pll_out = sample_rate * 384;
                        else
                                pll_out = sample_rate * 256;
@@ -353,7 +355,8 @@ static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
                return ret;
        }
 
-       if (sample_format == SNDRV_PCM_FORMAT_S24_LE)
+       if (sample_format == SNDRV_PCM_FORMAT_S24_LE
+               || sample_format == SNDRV_PCM_FORMAT_S20_3LE)
                pll_out = sample_rate * 384;
        else
                pll_out = sample_rate * 256;