diff options
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.patch | 119 |
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 + |