2015-05-12 07:10:45

by Zidan Wang

[permalink] [raw]
Subject: [alsa-devel][PATCH 1/4] ASoC: wm8960: Let wm8960 driver configure its bit clock and frame clock

wm8960 codec driver missing configure its bit clock and frame clock for codec
master mode, so add support for it. It will calculate a appropriate frequency
dividing ratio according to the system clock, bit clock and frame clock, then
set the corresponding registers.

Signed-off-by: Zidan Wang <[email protected]>
---
sound/soc/codecs/wm8960.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 101 insertions(+)

diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 6fa832b..b072501 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -127,6 +127,8 @@ struct wm8960_priv {
struct snd_soc_dapm_widget *out3;
bool deemph;
int playback_fs;
+ int bclk;
+ int sysclk;
struct wm8960_data pdata;
};

@@ -563,6 +565,72 @@ static struct {
{ 8000, 5 },
};

+/* Multiply 256 for internal 256 div */
+static const int dac_divs[] = { 256, 384, 512, 768, 1024, 1408, 1536 };
+
+/* Multiply 10 to eliminate decimials */
+static const int bclk_divs[] = {
+ 10, 15, 20, 30, 40, 55, 60, 80, 110,
+ 120, 160, 220, 240, 320, 320, 320
+};
+
+static void wm8960_configure_clocking(struct snd_soc_codec *codec,
+ bool tx, int lrclk)
+{
+ struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+ u16 iface1 = snd_soc_read(codec, WM8960_IFACE1);
+ u16 iface2 = snd_soc_read(codec, WM8960_IFACE2);
+ u32 sysclk;
+ int i, j;
+
+ if (!(iface1 & (1<<6))) {
+ dev_dbg(codec->dev,
+ "Codec is slave mode, no need to configure clock\n");
+ return;
+ }
+
+ if (!wm8960->sysclk) {
+ dev_dbg(codec->dev, "No SYSCLK configured\n");
+ return;
+ }
+
+ if (!wm8960->bclk || !lrclk) {
+ dev_dbg(codec->dev, "No audio clocks configured\n");
+ return;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(dac_divs); ++i) {
+ if (wm8960->sysclk == lrclk * dac_divs[i]) {
+ for (j = 0; j < ARRAY_SIZE(bclk_divs); ++j) {
+ sysclk = wm8960->bclk * bclk_divs[j] / 10;
+ if (wm8960->sysclk == sysclk)
+ break;
+ }
+ if(j != ARRAY_SIZE(bclk_divs))
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(dac_divs)) {
+ dev_err(codec->dev, "Unsupported sysclk %d\n", wm8960->sysclk);
+ return;
+ }
+
+ /*
+ * configure frame clock. If ADCLRC configure as GPIO pin, DACLRC
+ * pin is used as a frame clock for ADCs and DACs.
+ */
+ if (iface2 & (1<<6))
+ snd_soc_update_bits(codec, WM8960_CLOCK1, 0x7 << 3, i << 3);
+ else if (tx)
+ snd_soc_update_bits(codec, WM8960_CLOCK1, 0x7 << 3, i << 3);
+ else if (!tx)
+ snd_soc_update_bits(codec, WM8960_CLOCK1, 0x7 << 6, i << 6);
+
+ /* configure bit clock */
+ snd_soc_update_bits(codec, WM8960_CLOCK2, 0xf, j);
+}
+
static int wm8960_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -570,8 +638,13 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_codec *codec = dai->codec;
struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
int i;

+ wm8960->bclk = snd_soc_params_to_bclk(params);
+ if (params_channels(params) == 1)
+ wm8960->bclk *= 2;
+
/* bit size */
switch (params_width(params)) {
case 16:
@@ -602,6 +675,9 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,

/* set iface */
snd_soc_write(codec, WM8960_IFACE1, iface);
+
+ wm8960_configure_clocking(codec, tx, params_rate(params));
+
return 0;
}

@@ -946,6 +1022,30 @@ static int wm8960_set_bias_level(struct snd_soc_codec *codec,
return wm8960->set_bias_level(codec, level);
}

+static int wm8960_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+
+ switch (clk_id) {
+ case WM8960_SYSCLK_MCLK:
+ snd_soc_update_bits(codec, WM8960_CLOCK1,
+ 0x1, WM8960_SYSCLK_MCLK);
+ break;
+ case WM8960_SYSCLK_PLL:
+ snd_soc_update_bits(codec, WM8960_CLOCK1,
+ 0x1, WM8960_SYSCLK_PLL);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ wm8960->sysclk = freq;
+
+ return 0;
+}
+
#define WM8960_RATES SNDRV_PCM_RATE_8000_48000

#define WM8960_FORMATS \
@@ -958,6 +1058,7 @@ static const struct snd_soc_dai_ops wm8960_dai_ops = {
.set_fmt = wm8960_set_dai_fmt,
.set_clkdiv = wm8960_set_dai_clkdiv,
.set_pll = wm8960_set_dai_pll,
+ .set_sysclk = wm8960_set_dai_sysclk,
};

static struct snd_soc_dai_driver wm8960_dai = {
--
1.9.1


2015-05-12 06:56:44

by Zidan Wang

[permalink] [raw]
Subject: [alsa-devel][PATCH 2/4] ASoC: wm8960: add 32 bit word length support

According to referance manual, right justify mode can't
support 32 bit word length.

Signed-off-by: Zidan Wang <[email protected]>
---
sound/soc/codecs/wm8960.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index b072501..2559e31 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -655,6 +655,12 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
case 24:
iface |= 0x0008;
break;
+ case 32:
+ /* right justify mode does not support 32 word length */
+ if ((iface & 0x3) != 0) {
+ iface |= 0x000c;
+ break;
+ }
default:
dev_err(codec->dev, "unsupported width %d\n",
params_width(params));
@@ -1050,7 +1056,7 @@ static int wm8960_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,

#define WM8960_FORMATS \
(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE)
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)

static const struct snd_soc_dai_ops wm8960_dai_ops = {
.hw_params = wm8960_hw_params,
--
1.9.1

2015-05-12 07:12:11

by Zidan Wang

[permalink] [raw]
Subject: [alsa-devel][PATCH 3/4] ASoC: wm8960: fix "RINPUT3" audio route error

It should be "RINPUT3" instead of "LINPUT3" route to "Right Input
Mixer".

Signed-off-by: Zidan Wang <[email protected]>
---
sound/soc/codecs/wm8960.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 2559e31..4ab1607 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -397,7 +397,7 @@ static const struct snd_soc_dapm_route audio_paths[] = {
{ "Right Input Mixer", "Boost Switch", "Right Boost Mixer", },
{ "Right Input Mixer", NULL, "RINPUT1", }, /* Really Boost Switch */
{ "Right Input Mixer", NULL, "RINPUT2" },
- { "Right Input Mixer", NULL, "LINPUT3" },
+ { "Right Input Mixer", NULL, "RINPUT3" },

{ "Left ADC", NULL, "Left Input Mixer" },
{ "Right ADC", NULL, "Right Input Mixer" },
--
1.9.1

2015-05-12 06:57:16

by Zidan Wang

[permalink] [raw]
Subject: [alsa-devel][PATCH 4/4] ASoC: wm8958: correct BCLK DIV 348 to 384

According to the RM of wm8958, BCLK DIV 348 doesn't exist, correct it
to 384.

Signed-off-by: Zidan Wang <[email protected]>
---
sound/soc/codecs/wm8994.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 2d32b54..33bf663 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -2752,7 +2752,7 @@ static struct {
};

static int fs_ratios[] = {
- 64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536
+ 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536
};

static int bclk_divs[] = {
--
1.9.1

2015-05-12 10:42:19

by Charles Keepax

[permalink] [raw]
Subject: Re: [alsa-devel][PATCH 3/4] ASoC: wm8960: fix "RINPUT3" audio route error

On Tue, May 12, 2015 at 02:58:36PM +0800, Zidan Wang wrote:
> It should be "RINPUT3" instead of "LINPUT3" route to "Right Input
> Mixer".
>
> Signed-off-by: Zidan Wang <[email protected]>
> ---

Acked-by: Charles Keepax <[email protected]>

Better to put bug fixes like this at the start of a series if
possible.

Thanks,
Charles

2015-05-12 10:43:45

by Charles Keepax

[permalink] [raw]
Subject: Re: [alsa-devel][PATCH 4/4] ASoC: wm8958: correct BCLK DIV 348 to 384

On Tue, May 12, 2015 at 02:58:50PM +0800, Zidan Wang wrote:
> According to the RM of wm8958, BCLK DIV 348 doesn't exist, correct it
> to 384.
>
> Signed-off-by: Zidan Wang <[email protected]>
> ---

Acked-by: Charles Keepax <[email protected]>

Thanks,
Charles

2015-05-12 10:56:15

by Charles Keepax

[permalink] [raw]
Subject: Re: [alsa-devel][PATCH 2/4] ASoC: wm8960: add 32 bit word length support

On Tue, May 12, 2015 at 02:58:21PM +0800, Zidan Wang wrote:
> According to referance manual, right justify mode can't
> support 32 bit word length.
>
> Signed-off-by: Zidan Wang <[email protected]>
> ---

Acked-by: Charles Keepax <[email protected]>

Thanks,
Charles

2015-05-12 19:06:14

by Mark Brown

[permalink] [raw]
Subject: Re: [alsa-devel][PATCH 1/4] ASoC: wm8960: Let wm8960 driver configure its bit clock and frame clock

On Tue, May 12, 2015 at 02:58:08PM +0800, Zidan Wang wrote:
> wm8960 codec driver missing configure its bit clock and frame clock for codec
> master mode, so add support for it. It will calculate a appropriate frequency
> dividing ratio according to the system clock, bit clock and frame clock, then
> set the corresponding registers.

Applied all, thanks.


Attachments:
(No filename) (357.00 B)
signature.asc (473.00 B)
Digital signature
Download all attachments