MLK-16007-1: ASoC: fsl_asrc: Fix automatic mode configuration
authorMihai Serban <mihai.serban@nxp.com>
Wed, 26 Jul 2017 13:24:29 +0000 (16:24 +0300)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:36:10 +0000 (15:36 -0500)
Fix configuration for automatic selection of processing options and
internal measured ratio.

ASRC can automatically select its pre-processing and post-processing
options based on the frequencies it detects. To use this option the
two parameter registers ASR76K and ASR56K must be correctly configured
based on IPG clock frequency and the corresponding ATSx bits from the
ASRCTR register must be set.

When both the input sampling clock and the output sampling clock are
physically available, the rate conversion can work by configuring the
physical clocks. For this use case the ASRCTR:USRx and ASRCTR:IRDx
bits have to be configured as 1 and 0 respectively.

Signed-off-by: Mihai Serban <mihai.serban@nxp.com>
Reviewed-by: Shengjiu Wang <shengjiu.wang@nxp.com>
sound/soc/fsl/fsl_asrc.c

index 520b9a9..53bc307 100644 (file)
@@ -416,8 +416,11 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool p2p_in, bool p2
        /* Default setting: Automatic selection for processing mode */
        regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
                           ASRCTR_ATSi_MASK(index), ASRCTR_ATS(index));
+
+       /* Default setting: use internal measured ratio */
        regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
-                          ASRCTR_USRi_MASK(index), 0);
+                          ASRCTR_USRi_MASK(index) | ASRCTR_IDRi_MASK(index),
+                          ASRCTR_USR(index));
 
        /* Set the input and output clock sources */
        regmap_update_bits(asrc_priv->regmap, REG_ASRCSR,
@@ -918,6 +921,8 @@ static void fsl_asrc_reset(struct snd_pcm_substream *substream, bool stop)
  */
 static int fsl_asrc_init(struct fsl_asrc *asrc_priv)
 {
+       unsigned long ipg_rate;
+
        /* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
        regmap_write(asrc_priv->regmap, REG_ASRCTR, ASRCTR_ASRCEN);
 
@@ -935,11 +940,12 @@ static int fsl_asrc_init(struct fsl_asrc *asrc_priv)
        regmap_update_bits(asrc_priv->regmap, REG_ASRTFR1,
                           ASRTFR1_TF_BASE_MASK, ASRTFR1_TF_BASE(0xfc));
 
-       /* Set the processing clock for 76KHz to 133M */
-       regmap_write(asrc_priv->regmap, REG_ASR76K, 0x06D6);
-
-       /* Set the processing clock for 56KHz to 133M */
-       return regmap_write(asrc_priv->regmap, REG_ASR56K, 0x0947);
+       ipg_rate = clk_get_rate(asrc_priv->ipg_clk);
+       /* Set the period of the 76KHz and 56KHz sampling clocks based on
+        * the ASRC processing clock.
+        */
+       regmap_write(asrc_priv->regmap, REG_ASR76K, ipg_rate / 76000);
+       return regmap_write(asrc_priv->regmap, REG_ASR56K, ipg_rate / 56000);
 }
 
 /**