summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2018-12-18 16:08:14 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:35:41 +0800
commitf1459e0be38a89230f9c4831d6d7c0021b1ffc48 (patch)
tree3a3603877874666f893861a94ecb921ac9aa05f0 /sound
parentb7a1fa71b291893bd2f36e6f3719d56e74aa37fb (diff)
MLK-20613: ASoC: fsl_asrc: add limitation for non ideal ratio mode
for non ideal ratio mode, the clock rate should divide the sample rate with no remainder, and the quotient should be less than 1024. Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/fsl/fsl_asrc.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 43e3d6f74421..04e61aa6fc9b 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -305,7 +305,8 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool p2p_in, bool p2
struct fsl_asrc *asrc_priv = pair->asrc_priv;
enum asrc_pair_index index = pair->index;
u32 inrate, outrate, indiv, outdiv;
- u32 clk_index[2], div[2];
+ u32 clk_index[2], div[2], rem[2];
+ u64 clk_rate;
int in, out, channels;
int pre_proc, post_proc;
struct clk *clk;
@@ -365,8 +366,9 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool p2p_in, bool p2
/* We only have output clock for ideal ratio mode */
clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]];
-
- div[IN] = clk_get_rate(clk) / inrate;
+ clk_rate = clk_get_rate(clk);
+ rem[IN] = do_div(clk_rate, inrate);
+ div[IN] = (u32)clk_rate;
if (div[IN] == 0) {
pair_err("failed to support input sample rate %dHz by asrck_%x\n",
inrate, clk_index[ideal ? OUT : IN]);
@@ -381,11 +383,14 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool p2p_in, bool p2
* When M2M mode, output rate should also need to align with the out
* samplerate, but M2M must use less time to achieve good performance.
*/
- if (p2p_out || p2p_in)
- div[OUT] = clk_get_rate(clk) / outrate;
- else
- div[OUT] = clk_get_rate(clk) / IDEAL_RATIO_RATE;
-
+ clk_rate = clk_get_rate(clk);
+ if (p2p_out || p2p_in || (!ideal)) {
+ rem[OUT] = do_div(clk_rate, outrate);
+ div[OUT] = clk_rate;
+ } else {
+ rem[OUT] = do_div(clk_rate, IDEAL_RATIO_RATE);
+ div[OUT] = clk_rate;
+ }
if (div[OUT] == 0) {
pair_err("failed to support output sample rate %dHz by asrck_%x\n",
@@ -393,7 +398,13 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool p2p_in, bool p2
return -EINVAL;
}
- if (div[IN] > 1024 && div[OUT] > 1024) {
+ if (!ideal && (div[IN] > 1024 || div[OUT] > 1024 ||
+ rem[IN] != 0 || rem[OUT] != 0)) {
+ pair_err("The divider can't be used for non ideal mode\n");
+ return -EINVAL;
+ }
+
+ if (ideal && div[IN] > 1024 && div[OUT] > 1024) {
pair_warn("both divider (%d, %d) are larger than threshold\n",
div[IN], div[OUT]);
}