From: Nicolin Chen Date: Tue, 6 May 2014 08:56:01 +0000 (+0800) Subject: ASoC: fsl_esai: Bypass divider settings if clock requirement is not changed X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=b625c4b9cef29778e96b7f8836632540aff62950;p=karo-tx-linux.git ASoC: fsl_esai: Bypass divider settings if clock requirement is not changed We don't need to change those dividers if bclk and mclk remains the same directions and values. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown (cherry picked from commit f975ca46f634660a52d8c815b465258ae9bce3b7) --- diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index e05b17ba1e08..76fe8833a623 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -38,6 +38,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 @@ -54,6 +56,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; @@ -212,6 +216,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; @@ -277,6 +285,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, @@ -294,9 +303,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) @@ -319,8 +329,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,