diff options
author | Shengjiu Wang <shengjiu.wang@freescale.com> | 2014-12-08 15:20:41 +0800 |
---|---|---|
committer | Dong Aisheng <aisheng.dong@nxp.com> | 2019-11-25 15:48:21 +0800 |
commit | f54a93b477539524740ca786de646b9b0b571822 (patch) | |
tree | 7c9d99e1f2fc7dd59d9643eb82d869345e03d841 /sound/soc | |
parent | 200a083afb686fe60bc0f84ebf7e5b76ab5d071d (diff) |
MLK-10048-5: ASoC: fsl_asrc: underrun for playback 192k, 6ch p2p case.
For p2p output, the output divider should align with the output sample
rate, if use the Ideal sample rate, there will be a lot of overload, which
will cause underrun.
Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
(cherry picked from commit 5ab043f1a020ae8c3aeb3d91f6894bbd6a6ec147)
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/fsl/fsl_asrc.c | 33 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_asrc.h | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_asrc_m2m.c | 4 |
3 files changed, 26 insertions, 13 deletions
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c index f545009a90d7..ab071ff968ca 100644 --- a/sound/soc/fsl/fsl_asrc.c +++ b/sound/soc/fsl/fsl_asrc.c @@ -262,7 +262,7 @@ static int fsl_asrc_set_ideal_ratio(struct fsl_asrc_pair *pair, * of struct asrc_config which includes in/output sample rate, width, channel * and clock settings. */ -static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair) +static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool p2p_in, bool p2p_out) { struct asrc_config *config = pair->config; struct fsl_asrc *asrc_priv = pair->asrc_priv; @@ -337,11 +337,17 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair) clk = asrc_priv->asrck_clk[clk_index[OUT]]; - /* Use fixed output rate for Ideal Ratio mode (INCLK_NONE) */ - if (ideal) - div[OUT] = clk_get_rate(clk) / IDEAL_RATIO_RATE; - else + /* + * When P2P mode, output rate should align with the out samplerate. + * if set too high output rate, there will be lots of Overload. + * 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) div[OUT] = clk_get_rate(clk) / outrate; + else + div[OUT] = clk_get_rate(clk) / IDEAL_RATIO_RATE; + if (div[OUT] == 0) { pair_err("failed to support output sample rate %dHz by asrck_%x\n", @@ -535,17 +541,24 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream, config.output_word_width = word_width; config.input_sample_rate = rate; config.output_sample_rate = asrc_priv->asrc_rate; + + ret = fsl_asrc_config_pair(pair, false, true); + if (ret) { + dev_err(dai->dev, "fail to config asrc pair\n"); + return ret; + } + } else { config.input_word_width = word_width; config.output_word_width = width; config.input_sample_rate = asrc_priv->asrc_rate; config.output_sample_rate = rate; - } - ret = fsl_asrc_config_pair(pair); - if (ret) { - dev_err(dai->dev, "fail to config asrc pair\n"); - return ret; + ret = fsl_asrc_config_pair(pair, true, false); + if (ret) { + dev_err(dai->dev, "fail to config asrc pair\n"); + return ret; + } } return 0; diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index 0c07304bbd89..d958c5dd6b2d 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h @@ -25,7 +25,7 @@ #define ASRC_OUTPUT_LAST_SAMPLE_MAX 32 #define ASRC_OUTPUT_LAST_SAMPLE 16 -#define IDEAL_RATIO_RATE 1000000 +#define IDEAL_RATIO_RATE 200000 #define REG_ASRCTR 0x00 #define REG_ASRIER 0x04 diff --git a/sound/soc/fsl/fsl_asrc_m2m.c b/sound/soc/fsl/fsl_asrc_m2m.c index 1ae6aa7b739b..a7defb59bfcf 100644 --- a/sound/soc/fsl/fsl_asrc_m2m.c +++ b/sound/soc/fsl/fsl_asrc_m2m.c @@ -1,7 +1,7 @@ /* * Freescale ASRC Memory to Memory (M2M) driver * - * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -538,7 +538,7 @@ static long fsl_asrc_ioctl_config_pair(struct fsl_asrc_pair *pair, index = config.pair; pair->config = &config; - ret = fsl_asrc_config_pair(pair); + ret = fsl_asrc_config_pair(pair, false, false); if (ret) { pair_err("failed to config pair: %ld\n", ret); return ret; |