diff options
author | Shengjiu Wang <shengjiu.wang@nxp.com> | 2018-12-18 16:08:14 +0800 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:35:41 +0800 |
commit | f1459e0be38a89230f9c4831d6d7c0021b1ffc48 (patch) | |
tree | 3a3603877874666f893861a94ecb921ac9aa05f0 /sound | |
parent | b7a1fa71b291893bd2f36e6f3719d56e74aa37fb (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.c | 29 |
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]); } |