aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl/fsl_esai.c
diff options
context:
space:
mode:
authorNicolin Chen <Guangyu.Chen@freescale.com>2014-05-06 04:56:01 -0400
committerMark Brown <broonie@linaro.org>2014-05-12 18:15:25 -0400
commitf975ca46f634660a52d8c815b465258ae9bce3b7 (patch)
tree781c34ceec8d6463c57f59f8305db607eaca9f0f /sound/soc/fsl/fsl_esai.c
parent3e185238a37d1f0a37a1d910344cdcff578bf333 (diff)
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 <Guangyu.Chen@freescale.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/fsl/fsl_esai.c')
-rw-r--r--sound/soc/fsl/fsl_esai.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 67d5417e0933..0edc837ea3d7 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -39,6 +39,8 @@
39 * @fifo_depth: depth of tx/rx FIFO 39 * @fifo_depth: depth of tx/rx FIFO
40 * @slot_width: width of each DAI slot 40 * @slot_width: width of each DAI slot
41 * @hck_rate: clock rate of desired HCKx clock 41 * @hck_rate: clock rate of desired HCKx clock
42 * @sck_rate: clock rate of desired SCKx clock
43 * @hck_dir: the direction of HCKx pads
42 * @sck_div: if using PSR/PM dividers for SCKx clock 44 * @sck_div: if using PSR/PM dividers for SCKx clock
43 * @slave_mode: if fully using DAI slave mode 45 * @slave_mode: if fully using DAI slave mode
44 * @synchronous: if using tx/rx synchronous mode 46 * @synchronous: if using tx/rx synchronous mode
@@ -55,6 +57,8 @@ struct fsl_esai {
55 u32 fifo_depth; 57 u32 fifo_depth;
56 u32 slot_width; 58 u32 slot_width;
57 u32 hck_rate[2]; 59 u32 hck_rate[2];
60 u32 sck_rate[2];
61 bool hck_dir[2];
58 bool sck_div[2]; 62 bool sck_div[2];
59 bool slave_mode; 63 bool slave_mode;
60 bool synchronous; 64 bool synchronous;
@@ -213,6 +217,10 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
213 unsigned long clk_rate; 217 unsigned long clk_rate;
214 int ret; 218 int ret;
215 219
220 /* Bypass divider settings if the requirement doesn't change */
221 if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx])
222 return 0;
223
216 /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */ 224 /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */
217 esai_priv->sck_div[tx] = true; 225 esai_priv->sck_div[tx] = true;
218 226
@@ -272,6 +280,7 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
272 esai_priv->sck_div[tx] = false; 280 esai_priv->sck_div[tx] = false;
273 281
274out: 282out:
283 esai_priv->hck_dir[tx] = dir;
275 esai_priv->hck_rate[tx] = freq; 284 esai_priv->hck_rate[tx] = freq;
276 285
277 regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR, 286 regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
@@ -289,9 +298,10 @@ static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
289 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 298 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
290 u32 hck_rate = esai_priv->hck_rate[tx]; 299 u32 hck_rate = esai_priv->hck_rate[tx];
291 u32 sub, ratio = hck_rate / freq; 300 u32 sub, ratio = hck_rate / freq;
301 int ret;
292 302
293 /* Don't apply for fully slave mode*/ 303 /* Don't apply for fully slave mode or unchanged bclk */
294 if (esai_priv->slave_mode) 304 if (esai_priv->slave_mode || esai_priv->sck_rate[tx] == freq)
295 return 0; 305 return 0;
296 306
297 if (ratio * freq > hck_rate) 307 if (ratio * freq > hck_rate)
@@ -313,8 +323,15 @@ static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
313 return -EINVAL; 323 return -EINVAL;
314 } 324 }
315 325
316 return fsl_esai_divisor_cal(dai, tx, ratio, true, 326 ret = fsl_esai_divisor_cal(dai, tx, ratio, true,
317 esai_priv->sck_div[tx] ? 0 : ratio); 327 esai_priv->sck_div[tx] ? 0 : ratio);
328 if (ret)
329 return ret;
330
331 /* Save current bclk rate */
332 esai_priv->sck_rate[tx] = freq;
333
334 return 0;
318} 335}
319 336
320static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, 337static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,