diff options
author | Nicolin Chen <Guangyu.Chen@freescale.com> | 2014-04-30 06:54:05 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-05-05 15:26:05 -0400 |
commit | 9c6344b3fa547ce7ec78da95134d92d9f9309b31 (patch) | |
tree | 4fc10c4e0474c45a7facd093949e3c822bff94b7 /sound/soc/fsl | |
parent | 0b8643900a1bff32ad8bf17ef1f5d57b6d490502 (diff) |
ASoC: fsl_spdif: Use clk_set_rate() for spdif root clock only
The clock mux for the Freescale S/PDIF controller has eight clock sources
while most of them are from other moudles and even system clocks that do
not allow a rate-changing operation.
So we here only allow the clk_set_rate() and clk_round_rate() happened to
spdif root clock, the private clock for S/PDIF controller.
Signed-off-by: Nicolin Chen <Guangyu.Chen@freescale.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r-- | sound/soc/fsl/fsl_spdif.c | 15 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_spdif.h | 2 |
2 files changed, 14 insertions, 3 deletions
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 7ae2a25ea642..6df70a976c10 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c | |||
@@ -384,6 +384,10 @@ static int spdif_set_sample_rate(struct snd_pcm_substream *substream, | |||
384 | return -EINVAL; | 384 | return -EINVAL; |
385 | } | 385 | } |
386 | 386 | ||
387 | /* Don't mess up the clocks from other modules */ | ||
388 | if (clk != STC_TXCLK_SPDIF_ROOT) | ||
389 | goto clk_set_bypass; | ||
390 | |||
387 | /* | 391 | /* |
388 | * The S/PDIF block needs a clock of 64 * fs * div. The S/PDIF block | 392 | * The S/PDIF block needs a clock of 64 * fs * div. The S/PDIF block |
389 | * will divide by (div). So request 64 * fs * (div+1) which will | 393 | * will divide by (div). So request 64 * fs * (div+1) which will |
@@ -395,6 +399,7 @@ static int spdif_set_sample_rate(struct snd_pcm_substream *substream, | |||
395 | return ret; | 399 | return ret; |
396 | } | 400 | } |
397 | 401 | ||
402 | clk_set_bypass: | ||
398 | dev_dbg(&pdev->dev, "expected clock rate = %d\n", | 403 | dev_dbg(&pdev->dev, "expected clock rate = %d\n", |
399 | (64 * sample_rate * div)); | 404 | (64 * sample_rate * div)); |
400 | dev_dbg(&pdev->dev, "actual clock rate = %ld\n", | 405 | dev_dbg(&pdev->dev, "actual clock rate = %ld\n", |
@@ -1011,7 +1016,7 @@ static struct regmap_config fsl_spdif_regmap_config = { | |||
1011 | 1016 | ||
1012 | static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, | 1017 | static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, |
1013 | struct clk *clk, u64 savesub, | 1018 | struct clk *clk, u64 savesub, |
1014 | enum spdif_txrate index) | 1019 | enum spdif_txrate index, bool round) |
1015 | { | 1020 | { |
1016 | const u32 rate[] = { 32000, 44100, 48000 }; | 1021 | const u32 rate[] = { 32000, 44100, 48000 }; |
1017 | u64 rate_ideal, rate_actual, sub; | 1022 | u64 rate_ideal, rate_actual, sub; |
@@ -1019,7 +1024,10 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, | |||
1019 | 1024 | ||
1020 | for (div = 1; div <= 128; div++) { | 1025 | for (div = 1; div <= 128; div++) { |
1021 | rate_ideal = rate[index] * (div + 1) * 64; | 1026 | rate_ideal = rate[index] * (div + 1) * 64; |
1022 | rate_actual = clk_round_rate(clk, rate_ideal); | 1027 | if (round) |
1028 | rate_actual = clk_round_rate(clk, rate_ideal); | ||
1029 | else | ||
1030 | rate_actual = clk_get_rate(clk); | ||
1023 | 1031 | ||
1024 | arate = rate_actual / 64; | 1032 | arate = rate_actual / 64; |
1025 | arate /= div; | 1033 | arate /= div; |
@@ -1072,7 +1080,8 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv, | |||
1072 | if (!clk_get_rate(clk)) | 1080 | if (!clk_get_rate(clk)) |
1073 | continue; | 1081 | continue; |
1074 | 1082 | ||
1075 | ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index); | 1083 | ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index, |
1084 | i == STC_TXCLK_SPDIF_ROOT); | ||
1076 | if (savesub == ret) | 1085 | if (savesub == ret) |
1077 | continue; | 1086 | continue; |
1078 | 1087 | ||
diff --git a/sound/soc/fsl/fsl_spdif.h b/sound/soc/fsl/fsl_spdif.h index b1266790d117..18bf8cdc579e 100644 --- a/sound/soc/fsl/fsl_spdif.h +++ b/sound/soc/fsl/fsl_spdif.h | |||
@@ -157,6 +157,8 @@ enum spdif_gainsel { | |||
157 | #define STC_TXCLK_DIV(x) ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_TXCLK_DIV_MASK) | 157 | #define STC_TXCLK_DIV(x) ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_TXCLK_DIV_MASK) |
158 | #define STC_TXCLK_SRC_MAX 8 | 158 | #define STC_TXCLK_SRC_MAX 8 |
159 | 159 | ||
160 | #define STC_TXCLK_SPDIF_ROOT 1 | ||
161 | |||
160 | /* SPDIF tx rate */ | 162 | /* SPDIF tx rate */ |
161 | enum spdif_txrate { | 163 | enum spdif_txrate { |
162 | SPDIF_TXRATE_32000 = 0, | 164 | SPDIF_TXRATE_32000 = 0, |