ASoC: fsl_asrc: replace the process_option table with function
authorS.j. Wang <shengjiu.wang@nxp.com>
Wed, 15 May 2019 06:42:22 +0000 (06:42 +0000)
committerMark Brown <broonie@kernel.org>
Thu, 16 May 2019 12:37:01 +0000 (13:37 +0100)
When we want to support more sample rate, for example 12kHz/24kHz
we need update the process_option table, if we want to support more
sample rate next time, the table need to be updated again. which
is not flexible.

We got a function fsl_asrc_sel_proc to replace the table, which can
give the pre-processing and post-processing options according to
the sample rate.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/fsl/fsl_asrc.c

index 0b93792..71793d3 100644 (file)
 #define pair_dbg(fmt, ...) \
        dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
 
-/* Sample rates are aligned with that defined in pcm.h file */
-static const u8 process_option[][12][2] = {
-       /* 8kHz 11.025kHz 16kHz 22.05kHz 32kHz 44.1kHz 48kHz   64kHz   88.2kHz 96kHz   176kHz  192kHz */
-       {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 5512Hz */
-       {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 8kHz */
-       {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 11025Hz */
-       {{1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 16kHz */
-       {{1, 2}, {1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 22050Hz */
-       {{1, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},},      /* 32kHz */
-       {{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},},      /* 44.1kHz */
-       {{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},},      /* 48kHz */
-       {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},},      /* 64kHz */
-       {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},},      /* 88.2kHz */
-       {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},},      /* 96kHz */
-       {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},      /* 176kHz */
-       {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},      /* 192kHz */
-};
-
 /* Corresponding to process_option */
 static int supported_input_rate[] = {
        5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200,
@@ -80,6 +62,52 @@ static unsigned char output_clk_map_imx53[] = {
 static unsigned char *clk_map[2];
 
 /**
+ * Select the pre-processing and post-processing options
+ * Make sure to exclude following unsupported cases before
+ * calling this function:
+ * 1) inrate > 8.125 * outrate
+ * 2) inrate > 16.125 * outrate
+ *
+ * inrate: input sample rate
+ * outrate: output sample rate
+ * pre_proc: return value for pre-processing option
+ * post_proc: return value for post-processing option
+ */
+static void fsl_asrc_sel_proc(int inrate, int outrate,
+                            int *pre_proc, int *post_proc)
+{
+       bool post_proc_cond2;
+       bool post_proc_cond0;
+
+       /* select pre_proc between [0, 2] */
+       if (inrate * 8 > 33 * outrate)
+               *pre_proc = 2;
+       else if (inrate * 8 > 15 * outrate) {
+               if (inrate > 152000)
+                       *pre_proc = 2;
+               else
+                       *pre_proc = 1;
+       } else if (inrate < 76000)
+               *pre_proc = 0;
+       else if (inrate > 152000)
+               *pre_proc = 2;
+       else
+               *pre_proc = 1;
+
+       /* Condition for selection of post-processing */
+       post_proc_cond2 = (inrate * 15 > outrate * 16 && outrate < 56000) ||
+                         (inrate > 56000 && outrate < 56000);
+       post_proc_cond0 = inrate * 23 < outrate * 8;
+
+       if (post_proc_cond2)
+               *post_proc = 2;
+       else if (post_proc_cond0)
+               *post_proc = 0;
+       else
+               *post_proc = 1;
+}
+
+/**
  * Request ASRC pair
  *
  * It assigns pair by the order of A->C->B because allocation of pair B,
@@ -239,6 +267,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
        u32 inrate, outrate, indiv, outdiv;
        u32 clk_index[2], div[2];
        int in, out, channels;
+       int pre_proc, post_proc;
        struct clk *clk;
        bool ideal;
 
@@ -377,11 +406,13 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
                           ASRCTR_IDRi_MASK(index) | ASRCTR_USRi_MASK(index),
                           ASRCTR_IDR(index) | ASRCTR_USR(index));
 
+       fsl_asrc_sel_proc(inrate, outrate, &pre_proc, &post_proc);
+
        /* Apply configurations for pre- and post-processing */
        regmap_update_bits(asrc_priv->regmap, REG_ASRCFG,
                           ASRCFG_PREMODi_MASK(index) | ASRCFG_POSTMODi_MASK(index),
-                          ASRCFG_PREMOD(index, process_option[in][out][0]) |
-                          ASRCFG_POSTMOD(index, process_option[in][out][1]));
+                          ASRCFG_PREMOD(index, pre_proc) |
+                          ASRCFG_POSTMOD(index, post_proc));
 
        return fsl_asrc_set_ideal_ratio(pair, inrate, outrate);
 }