aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-3.14/0043-ASoC-wm8804-Implement-MCLK-configuration-options-add.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-3.14/0043-ASoC-wm8804-Implement-MCLK-configuration-options-add.patch')
-rw-r--r--target/linux/brcm2708/patches-3.14/0043-ASoC-wm8804-Implement-MCLK-configuration-options-add.patch119
1 files changed, 119 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-3.14/0043-ASoC-wm8804-Implement-MCLK-configuration-options-add.patch b/target/linux/brcm2708/patches-3.14/0043-ASoC-wm8804-Implement-MCLK-configuration-options-add.patch
new file mode 100644
index 0000000000..b1e1e7bb98
--- /dev/null
+++ b/target/linux/brcm2708/patches-3.14/0043-ASoC-wm8804-Implement-MCLK-configuration-options-add.patch
@@ -0,0 +1,119 @@
+From 0b1d46fef20d096cc3991df89ec793a10df0eaf2 Mon Sep 17 00:00:00 2001
+From: Daniel Matuschek <info@crazy-audio.com>
+Date: Wed, 15 Jan 2014 21:41:23 +0100
+Subject: [PATCH 43/54] ASoC: wm8804: Implement MCLK configuration options, add
+ 32bit support WM8804 can run with PLL frequencies of 256xfs and 128xfs for
+ most sample rates. At 192kHz only 128xfs is supported. The existing driver
+ selects 128xfs automatically for some lower samples rates. By using an
+ additional mclk_div divider, it is now possible to control the behaviour.
+ This allows using 256xfs PLL frequency on all sample rates up to 96kHz. It
+ should allow lower jitter and better signal quality. The behavior has to be
+ controlled by the sound card driver, because some sample frequency share the
+ same setting. e.g. 192kHz and 96kHz use 24.576MHz master clock. The only
+ difference is the MCLK divider.
+
+This also added support for 32bit data.
+
+Signed-off-by: Daniel Matuschek <daniel@matuschek.net>
+---
+ sound/soc/codecs/wm8804.c | 19 +++++++++++++++----
+ sound/soc/codecs/wm8804.h | 4 ++++
+ 2 files changed, 19 insertions(+), 4 deletions(-)
+
+diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
+index 9bc8206..c35b4f3 100644
+--- a/sound/soc/codecs/wm8804.c
++++ b/sound/soc/codecs/wm8804.c
+@@ -63,6 +63,7 @@ struct wm8804_priv {
+ struct regmap *regmap;
+ struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES];
+ struct notifier_block disable_nb[WM8804_NUM_SUPPLIES];
++ int mclk_div;
+ };
+
+ static int txsrc_get(struct snd_kcontrol *kcontrol,
+@@ -277,6 +278,7 @@ static int wm8804_hw_params(struct snd_pcm_substream *substream,
+ blen = 0x1;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
++ case SNDRV_PCM_FORMAT_S32_LE:
+ blen = 0x2;
+ break;
+ default:
+@@ -318,7 +320,7 @@ static struct {
+
+ #define FIXED_PLL_SIZE ((1ULL << 22) * 10)
+ static int pll_factors(struct pll_div *pll_div, unsigned int target,
+- unsigned int source)
++ unsigned int source, unsigned int mclk_div)
+ {
+ u64 Kpart;
+ unsigned long int K, Ndiv, Nmod, tmp;
+@@ -330,7 +332,8 @@ static int pll_factors(struct pll_div *pll_div, unsigned int target,
+ */
+ for (i = 0; i < ARRAY_SIZE(post_table); i++) {
+ tmp = target * post_table[i].div;
+- if (tmp >= 90000000 && tmp <= 100000000) {
++ if ((tmp >= 90000000 && tmp <= 100000000) &&
++ (mclk_div == post_table[i].mclkdiv)) {
+ pll_div->freqmode = post_table[i].freqmode;
+ pll_div->mclkdiv = post_table[i].mclkdiv;
+ target *= post_table[i].div;
+@@ -387,8 +390,11 @@ static int wm8804_set_pll(struct snd_soc_dai *dai, int pll_id,
+ } else {
+ int ret;
+ struct pll_div pll_div;
++ struct wm8804_priv *wm8804;
+
+- ret = pll_factors(&pll_div, freq_out, freq_in);
++ wm8804 = snd_soc_codec_get_drvdata(codec);
++
++ ret = pll_factors(&pll_div, freq_out, freq_in, wm8804->mclk_div);
+ if (ret)
+ return ret;
+
+@@ -452,6 +458,7 @@ static int wm8804_set_clkdiv(struct snd_soc_dai *dai,
+ int div_id, int div)
+ {
+ struct snd_soc_codec *codec;
++ struct wm8804_priv *wm8804;
+
+ codec = dai->codec;
+ switch (div_id) {
+@@ -459,6 +466,10 @@ static int wm8804_set_clkdiv(struct snd_soc_dai *dai,
+ snd_soc_update_bits(codec, WM8804_PLL5, 0x30,
+ (div & 0x3) << 4);
+ break;
++ case WM8804_MCLK_DIV:
++ wm8804 = snd_soc_codec_get_drvdata(codec);
++ wm8804->mclk_div = div;
++ break;
+ default:
+ dev_err(dai->dev, "Unknown clock divider: %d\n", div_id);
+ return -EINVAL;
+@@ -641,7 +652,7 @@ static const struct snd_soc_dai_ops wm8804_dai_ops = {
+ };
+
+ #define WM8804_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
+- SNDRV_PCM_FMTBIT_S24_LE)
++ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+ #define WM8804_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
+ SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \
+diff --git a/sound/soc/codecs/wm8804.h b/sound/soc/codecs/wm8804.h
+index 8ec14f5..e72d4f4 100644
+--- a/sound/soc/codecs/wm8804.h
++++ b/sound/soc/codecs/wm8804.h
+@@ -57,5 +57,9 @@
+ #define WM8804_CLKOUT_SRC_OSCCLK 4
+
+ #define WM8804_CLKOUT_DIV 1
++#define WM8804_MCLK_DIV 2
++
++#define WM8804_MCLKDIV_256FS 0
++#define WM8804_MCLKDIV_128FS 1
+
+ #endif /* _WM8804_H */
+--
+1.9.1
+