[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <a04859bff36ba26cb4cb51ff092a3f2e2eca455d.1554975348.git.shengjiu.wang@nxp.com>
Date: Thu, 11 Apr 2019 09:39:06 +0000
From: "S.j. Wang" <shengjiu.wang@....com>
To: "timur@...nel.org" <timur@...nel.org>,
"nicoleotsuka@...il.com" <nicoleotsuka@...il.com>,
"Xiubo.Lee@...il.com" <Xiubo.Lee@...il.com>,
"festevam@...il.com" <festevam@...il.com>,
"broonie@...nel.org" <broonie@...nel.org>,
"alsa-devel@...a-project.org" <alsa-devel@...a-project.org>
CC: "linuxppc-dev@...ts.ozlabs.org" <linuxppc-dev@...ts.ozlabs.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>
Subject: [PATCH V2 1/2] ASoC: fsl_asrc: replace the process_option table with
function
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@....com>
---
sound/soc/fsl/fsl_asrc.c | 87 +++++++++++++++++++++++++++++++++++++-----------
1 file changed, 67 insertions(+), 20 deletions(-)
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 0b937924d2e4..5857d383d962 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -26,24 +26,6 @@
#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,
@@ -79,6 +61,63 @@
static unsigned char *clk_map[2];
+/*
+ * Select the pre-processing and post-processing options
+ *
+ * Fsin: input sample rate
+ * Fsout: output sample rate
+ * pre_proc: return value for pre-processing option
+ * post_proc: return value for post-processing option
+ */
+static int fsl_asrc_sel_proc(int Fsin, int Fsout, int *pre_proc, int *post_proc)
+{
+ bool det_out_op2_cond;
+ bool det_out_op0_cond;
+
+ /* Codition for selection of post-processing */
+ det_out_op2_cond = (((Fsin * 15 > Fsout * 16) & (Fsout < 56000)) |
+ ((Fsin > 56000) & (Fsout < 56000)));
+ det_out_op0_cond = (Fsin * 23 < Fsout * 8);
+
+ /*
+ * unsupported case: Tsout>16.125*Tsin, and Tsout>8.125*Tsin.
+ * Tsout>16.125*Tsin -> Fsin * 8 > 129 * Fsout
+ * Tsout>8.125*Tsin -> Fsin * 8 > 65 * Fsout
+ * Tsout>4.125*Tsin -> Fsin * 8 > 33 * Fsout
+ * Tsout>1.875*Tsin -> Fsin * 8 > 15 * Fsout
+ */
+ if (Fsin * 8 > 129 * Fsout)
+ *pre_proc = 5;
+ else if (Fsin * 8 > 65 * Fsout)
+ *pre_proc = 4;
+ else if (Fsin * 8 > 33 * Fsout)
+ *pre_proc = 2;
+ else if (Fsin * 8 > 15 * Fsout) {
+ if (Fsin > 152000)
+ *pre_proc = 2;
+ else
+ *pre_proc = 1;
+ } else if (Fsin < 76000)
+ *pre_proc = 0;
+ else if (Fsin > 152000)
+ *pre_proc = 2;
+ else
+ *pre_proc = 1;
+
+ if (det_out_op2_cond)
+ *post_proc = 2;
+ else if (det_out_op0_cond)
+ *post_proc = 0;
+ else
+ *post_proc = 1;
+
+ /* unsupported options */
+ if (*pre_proc == 4 || *pre_proc == 5)
+ return -EINVAL;
+
+ return 0;
+}
+
/**
* Request ASRC pair
*
@@ -239,8 +278,10 @@ 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;
+ int ret;
if (!config) {
pair_err("invalid pair config\n");
@@ -289,6 +330,12 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
return -EINVAL;
}
+ ret = fsl_asrc_sel_proc(inrate, outrate, &pre_proc, &post_proc);
+ if (ret) {
+ pair_err("No supported pre-processing options\n");
+ return ret;
+ }
+
/* Validate input and output clock sources */
clk_index[IN] = clk_map[IN][config->inclk];
clk_index[OUT] = clk_map[OUT][config->outclk];
@@ -380,8 +427,8 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
/* 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);
}
--
1.9.1
Powered by blists - more mailing lists