On Wed, Dec 31, 2014 at 11:39:12AM +0800, Zidan Wang wrote:
wm8960 codec driver missing configure its bit clock and frame clock, 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 b50113@freescale.com
sound/soc/codecs/wm8960.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+)
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 1a5f47b..86a5489 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,79 @@ 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,
int stream, 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);
- 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) {
if (wm8960->sysclk == wm8960->bclk *
bclk_divs[j] / 10) {
/* configure frame clock */
if (iface2 & (1<<6))
/* If ADCLRC configure as GPIO
* pin, DACLRC pin is used as
* a frame clock for ADCs and
* DACs */
snd_soc_update_bits(codec,
WM8960_CLOCK1,
0x7 << 3,
i << 3);
The indentation is getting pretty horrific here can we do some things to ease that a little. You could flip the polarity of the two if statements and use continues instead for example that would help a lot.
Thanks, Charles
else if (SNDRV_PCM_STREAM_PLAYBACK
== stream)
snd_soc_update_bits(codec,
WM8960_CLOCK1,
0x7 << 3,
i << 3);
else if (SNDRV_PCM_STREAM_CAPTURE
== stream)
snd_soc_update_bits(codec,
WM8960_CLOCK1,
0x7 << 6,
i << 6);
/* configure bit clock */
snd_soc_update_bits(codec,
WM8960_CLOCK2, 0xf, j);
return;
}
}
}
- }
- dev_err(codec->dev, "Unsupported sysclk %d\n", wm8960->sysclk);
+}