diff options
author | Nicolin Chen <Guangyu.Chen@freescale.com> | 2014-05-06 04:56:01 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-05-12 18:15:25 -0400 |
commit | f975ca46f634660a52d8c815b465258ae9bce3b7 (patch) | |
tree | 781c34ceec8d6463c57f59f8305db607eaca9f0f /sound/soc/fsl/fsl_esai.c | |
parent | 3e185238a37d1f0a37a1d910344cdcff578bf333 (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.c | 23 |
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 | ||
274 | out: | 282 | out: |
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 | ||
320 | static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | 337 | static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, |