Skip to content

Commit

Permalink
ASoC: fsl_esai: Bypass divider settings if clock requirement is not c…
Browse files Browse the repository at this point in the history
…hanged

We don't need to change those dividers if bclk and mclk remains the same
directions and values.

Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
  • Loading branch information
Nicolin Chen authored and Mark Brown committed May 12, 2014
1 parent 3e18523 commit f975ca4
Showing 1 changed file with 20 additions and 3 deletions.
23 changes: 20 additions & 3 deletions sound/soc/fsl/fsl_esai.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -272,6 +280,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,
Expand All @@ -289,9 +298,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)
Expand All @@ -313,8 +323,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,
Expand Down

0 comments on commit f975ca4

Please sign in to comment.