ASoC: fsl_esai: Fix some issues
Subsystems (3)
cover ASoC: fsl_esai: Fix some issues
Sorry for this resend. I just found my previous patches have not been delivered successfully to the alsa maillist.
This series of patches fix the following problems:
PATCH-1 for an incorrect ratio range check.
PATCH-2 for an incorrect bypass settings of FSYS clock source. PATCH-3 for duplicated calculations and configurations of dividers PATCH-4 for mismatched init flow of configuration comparing to RM.
Nicolin Chen (4):
ASoC: fsl_esai: Fix incorrect condition within ratio range check for
FP
ASoC: fsl_esai: Only bypass sck_div for EXTAL source
ASoC: fsl_esai: Bypass divider settings if clock requirement is not
changed
ASoC: fsl_esai: Set PCRC and PRRC registers at the end of hw_params()
sound/soc/fsl/fsl_esai.c | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-)
Signature · 1 line
1.8.4
PATCH RESEND 1/4 ASoC: fsl_esai: Fix incorrect condition within ratio range check for FP
The range here from 1 to 16 is confined to FP divider only while the sck_div indicates if the calculation contains PSR and PM dividers. So for the case using PSR and PM since the sck_div is true, the range of ratio would simply become bigger than 16.
So this patch fixes the condition here and adds one line comments to make the purpose here clear.
--- sound/soc/fsl/fsl_esai.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/fsl/fsl_esai.c +2 -1
@@ -308,7 +308,8 @@ static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)return -EINVAL ; } -if (esai_priv->sck_div[tx] && (ratio >16 || ratio ==0 )) { +/* The ratio should be contented by FP alone if bypassing PM and PSR */ +if (!esai_priv->sck_div[tx] && (ratio >16 || ratio ==0 )) {dev_err (dai->dev,"the ratio is out of range (1 ~ 16)\n" );return -EINVAL ; }
Signature · 1 line
1.8.4
PATCH RESEND 2/4 ASoC: fsl_esai: Only bypass sck_div for EXTAL source
In reply to Nicolin ChenESAI can only output EXTAL clock source directly. But for FSYS clock source, ESAI can not output it without getting through PSR PM dividers.
So this patch adds an extra check in the code.
--- sound/soc/fsl/fsl_esai.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
sound/soc/fsl/fsl_esai.c +7 -1
@@ -259,10 +259,16 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,return -EINVAL ; } -if (ratio ==1 ) { +/* Only EXTAL source can be output directly without using PSR and PM */ +if (ratio ==1 && clksrc == esai_priv->extalclk) {/* Bypass all the dividers if not being needed */ ecr |= tx ?ESAI_ECR_ETO :ESAI_ECR_ERO ; goto out; + }else if (ratio <2 ) { +/* The ratio should be no less than 2 if using other sources */ +dev_err (dai->dev,"failed to derive required HCK%c rate\n" , + tx ?'T' :'R' ); +return -EINVAL ; } ret =fsl_esai_divisor_cal (dai, tx, ratio, false,0 );
Signature · 1 line
1.8.4
PATCH RESEND 3/4 ASoC: fsl_esai: Bypass divider settings if clock requirement is not changed
In reply to Nicolin ChenWe don't need to change those dividers if bclk and mclk remains the same directions and values.
--- sound/soc/fsl/fsl_esai.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-)
sound/soc/fsl/fsl_esai.c +20 -3
@@ -39,6 +39,8 @@* @fifo_depth: depth of tx/rx FIFO * @slot_width: width of each DAI slot * @hck_rate: clock rate of desired HCKx clock +* @sck_rate: clock rate of desired SCKx clock +* @hck_dir: the direction of HCKx pads * @sck_div: if using PSR/PM dividers for SCKx clock * @slave_mode: if fully using DAI slave mode * @synchronous: if using tx/rx synchronous mode
@@ -55,6 +57,8 @@ struct fsl_esai {u32 fifo_depth;u32 slot_width;u32 hck_rate[2 ]; +u32 sck_rate[2 ]; +bool hck_dir[2 ];bool sck_div[2 ];bool slave_mode;bool synchronous;
@@ -213,6 +217,10 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,unsigned long clk_rate;int ret; +/* Bypass divider settings if the requirement doesn't change */ +if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx]) +return 0 ; +/* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */ esai_priv->sck_div[tx] = true;
@@ -278,6 +286,7 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, esai_priv->sck_div[tx] = false; out: + esai_priv->hck_dir[tx] = dir; esai_priv->hck_rate[tx] = freq; regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
@@ -295,9 +304,10 @@ static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)struct fsl_esai *esai_priv =snd_soc_dai_get_drvdata (dai);u32 hck_rate = esai_priv->hck_rate[tx];u32 sub, ratio = hck_rate / freq; +int ret; -/* Don't apply for fully slave mode*/ -if (esai_priv->slave_mode) +/* Don't apply for fully slave mode or unchanged bclk */ +if (esai_priv->slave_mode || esai_priv->sck_rate[tx] == freq)return 0 ;if (ratio * freq > hck_rate)
@@ -320,8 +330,15 @@ static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)return -EINVAL ; } -return fsl_esai_divisor_cal (dai, tx, ratio, true, + ret =fsl_esai_divisor_cal (dai, tx, ratio, true, esai_priv->sck_div[tx] ?0 : ratio); +if (ret) +return ret; + +/* Save current bclk rate */ + esai_priv->sck_rate[tx] = freq; + +return 0 ; } static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
Signature · 1 line
1.8.4
PATCH RESEND 4/4 ASoC: fsl_esai: Set PCRC and PRRC registers at the end of hw_params()
In reply to Nicolin ChenAccording to Reference Manual -- ESAI Initialization chapter, as the standard procedure of ESAI personal reset, the PCRC and PRRC registers should be remained in its reset value and then configured after T/RCCR and T/RCR configurations's done but before TE/RE's enabling.
So this patch moves PCRC and PRRC settings to the end of hw_params().
--- sound/soc/fsl/fsl_esai.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
sound/soc/fsl/fsl_esai.c +5 -6
@@ -479,12 +479,6 @@ static int fsl_esai_startup(struct snd_pcm_substream *substream, }if (!dai->active) { -/* Reset Port C */ -regmap_update_bits (esai_priv->regmap,REG_ESAI_PRRC , -ESAI_PRRC_PDC_MASK ,ESAI_PRRC_PDC (ESAI_GPIO )); -regmap_update_bits (esai_priv->regmap,REG_ESAI_PCRC , -ESAI_PCRC_PC_MASK ,ESAI_PCRC_PC (ESAI_GPIO )); -/* Set synchronous mode */ regmap_update_bits(esai_priv->regmap, REG_ESAI_SAICR, ESAI_SAICR_SYNC, esai_priv->synchronous ?
@@ -545,6 +539,11 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,regmap_update_bits (esai_priv->regmap,REG_ESAI_xCR (tx), mask, val); +/* Remove ESAI personal reset by configuring ESAI_PCRC and ESAI_PRRC */ +regmap_update_bits (esai_priv->regmap,REG_ESAI_PRRC , +ESAI_PRRC_PDC_MASK ,ESAI_PRRC_PDC (ESAI_GPIO )); +regmap_update_bits (esai_priv->regmap,REG_ESAI_PCRC , +ESAI_PCRC_PC_MASK ,ESAI_PCRC_PC (ESAI_GPIO ));return 0 ; }
Signature · 1 line
1.8.4
Quoted 2 lines · Nicolin Chen
Sorry for this resend. I just found my previous patches have not been delivered successfully to the alsa maillist.
Applied all, thanks.