天天看點

S3C64XX Smartq WM8987 Codec 2.6.27/2.6.30

--- wm8987.c 2009-12-02 20:18:49.000000000 +0800

+++ /work2/task/linux-kernel-2.6.24.7-smartq/sound/soc/codecs/wm8987.c 2009-12-01 12:03:39.000000000 +0800

@@ -6,9 +6,6 @@

* Author: Richard Purdie <[email protected]>

*

* Based on WM8987.c

- *

- * Jiujin.hong<hongjiujing.gmail.com> implement Kernel 2.6.27 New Alsa Sound Arch Code Framework 2009.Dec

- * For S3C64XX/Smartq5/Smartq7 Kernel

*

* This program is free software; you can redistribute it and/or modify

* it under the terms of the GNU General Public License version 2 as

@@ -22,6 +19,7 @@

#include <linux/pm.h>

#include <linux/i2c.h>

#include <linux/platform_device.h>

+#include <sound/driver.h>

#include <sound/core.h>

#include <sound/pcm.h>

#include <sound/pcm_params.h>

@@ -46,7 +44,7 @@

* Debug

*/

-//#define WM8987_DEBUG 0

+//#define WM8987_DEBUG 1

#ifdef WM8987_DEBUG

#define dbg(format, arg...) /

@@ -133,8 +131,7 @@

unsigned int value)

{

u8 data[2];

-// int pin_level = gpio_get_value(S3C_GPL12);

- int pin_level=0;

+ int pin_level = gpio_get_value(S3C_GPL12);

#if 0 //def CONFIG_SND_SOC_WM8987

if((10 == reg || 11 == reg) && value == 0x1C2) value = 0x1C4;

@@ -255,7 +252,6 @@

SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8987_LOUT1V,

WM8987_ROUT1V, 7, 1, 0),

#endif

-

SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8987_LOUT2V,

WM8987_ROUT2V, 7, 1, 0),

@@ -673,7 +669,7 @@

}

#if 1 //lzcx

-static int wm8987_set_dai_clkdiv(struct snd_soc_dai *codec_dai,

+static int wm8987_set_dai_clkdiv(struct snd_soc_codec_dai *codec_dai,

int div_id, int div)

{

struct snd_soc_codec *codec = codec_dai->codec;

@@ -705,7 +701,7 @@

}

#endif

-static int wm8987_set_dai_sysclk(struct snd_soc_dai *codec_dai,

+static int wm8987_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,

int clk_id, unsigned int freq, int dir)

{

#ifndef CONFIG_HHTECH_MINIPMP

@@ -731,7 +727,7 @@

return -EINVAL;

}

-static int wm8987_set_dai_fmt(struct snd_soc_dai *codec_dai,

+static int wm8987_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,

unsigned int fmt)

{

struct snd_soc_codec *codec = codec_dai->codec;

@@ -844,7 +840,7 @@

return 0;

}

-static int wm8987_mute(struct snd_soc_dai *dai, int mute)

+static int wm8987_mute(struct snd_soc_codec_dai *dai, int mute)

{

struct snd_soc_codec *codec = dai->codec;

u16 mute_reg = wm8987_read_reg_cache(codec, WM8987_ADCDAC) & 0xfff7;

@@ -870,33 +866,32 @@

return 0;

}

-static int wm8987_set_bias_level(struct snd_soc_codec *codec,

- enum snd_soc_bias_level level)

+static int wm8987_dapm_event(struct snd_soc_codec *codec, int event)

{

u16 pwr_reg = wm8987_read_reg_cache(codec, WM8987_PWR1) & 0xfe3e;

pwr_reg |= 0x2;//lzcx micbias on

- switch (level) {

- case SND_SOC_BIAS_ON:

+ switch (event) {

+ case SNDRV_CTL_POWER_D0:

wm8987_write(codec, WM8987_PWR1, pwr_reg | 0x00c0);

break;

- case SND_SOC_BIAS_PREPARE:

+ case SNDRV_CTL_POWER_D1:

wm8987_write(codec, WM8987_PWR1, pwr_reg | 0x01c0);

break;

case SNDRV_CTL_POWER_D2:

wm8987_write(codec, WM8987_PWR1, pwr_reg | 0x01c1);

break;

- case SND_SOC_BIAS_STANDBY:

+ case SNDRV_CTL_POWER_D3hot:

wm8987_write(codec, WM8987_PWR1, pwr_reg | 0x0141);

break;

- case SND_SOC_BIAS_OFF:

+ case SNDRV_CTL_POWER_D3cold:

wm8987_write(codec, WM8987_PWR1, 0x0001);

break;

}

- codec->bias_level = level;

+ codec->dapm_state = event;

return 0;

}

@@ -906,11 +901,10 @@

SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | /

SNDRV_PCM_RATE_96000)

-

#define WM8987_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | /

SNDRV_PCM_FMTBIT_S24_LE)

-struct snd_soc_dai wm8987_dai = {

+struct snd_soc_codec_dai wm8987_dai = {

.name = "WM8987",

.playback = {

.stream_name = "Playback",

@@ -939,8 +933,12 @@

static void wm8987_work(struct work_struct *work)

{

struct snd_soc_codec *codec =

+//#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)

+// (struct snd_soc_codec*)work; // XXX:

+//#else// XXX: mhfan

container_of(work, struct snd_soc_codec, delayed_work.work);

- wm8987_set_bias_level(codec, codec->bias_level);

+//#endif//LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)

+ wm8987_dapm_event(codec, codec->dapm_state);

}

static int wm8987_suspend(struct platform_device *pdev, pm_message_t state)

@@ -948,7 +946,7 @@

struct snd_soc_device *socdev = platform_get_drvdata(pdev);

struct snd_soc_codec *codec = socdev->codec;

- wm8987_set_bias_level(codec, SND_SOC_BIAS_OFF);

+ wm8987_dapm_event(codec, SNDRV_CTL_POWER_D3cold);

return 0;

}

@@ -969,14 +967,13 @@

codec->hw_write(codec->control_data, data, 2);

}

- wm8987_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

+ wm8987_dapm_event(codec, SNDRV_CTL_POWER_D3hot);

if (codec->suspend_dapm_state == SNDRV_CTL_POWER_D0) {

- wm8987_set_bias_level(codec, SND_SOC_BIAS_PREPARE);

- codec->bias_level = SND_SOC_BIAS_ON;

- schedule_delayed_work(&codec->delayed_work,

- msecs_to_jiffies(1000));

+ wm8987_dapm_event(codec, SNDRV_CTL_POWER_D2);

+ codec->dapm_state = SNDRV_CTL_POWER_D0;

+ schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000));

}

return 0;

@@ -1006,7 +1003,7 @@

codec->owner = THIS_MODULE;

codec->read = wm8987_read_reg_cache;

codec->write = wm8987_write;

- codec->set_bias_level = wm8987_set_bias_level;

+ codec->dapm_event = wm8987_dapm_event;

codec->dai = &wm8987_dai;

codec->num_dai = 1;

#ifndef CONFIG_HHTECH_MINIPMP

@@ -1039,10 +1036,8 @@

}

- wm8987_set_bias_level(codec, SND_SOC_BIAS_PREPARE);

- codec->bias_level = SND_SOC_BIAS_STANDBY;

-

-

+ wm8987_dapm_event(codec, SNDRV_CTL_POWER_D1); // XXX:

+ codec->dapm_state = SNDRV_CTL_POWER_D3hot;

schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000));

#ifdef CONFIG_HHTECH_MINIPMP

@@ -1075,12 +1070,10 @@

reg = wm8987_read_reg_cache(codec, WM8987_LDAC);

//wm8987_write(codec, WM8987_LDAC, 0x0100);

-// wm8987_write(codec, WM8987_LDAC, 0x01c7);

- wm8987_write(codec, WM8987_LDAC, 0x1ff);

+ wm8987_write(codec, WM8987_LDAC, 0x01c7);

reg = wm8987_read_reg_cache(codec, WM8987_RDAC);

//wm8987_write(codec, WM8987_RDAC, 0x0100);

-// wm8987_write(codec, WM8987_RDAC, 0x01c7);

- wm8987_write(codec, WM8987_RDAC, 0x1ff);

+ wm8987_write(codec, WM8987_RDAC, 0x01c7);

reg = wm8987_read_reg_cache(codec, WM8987_LINVOL);

wm8987_write(codec, WM8987_LINVOL, (reg & ~0x080) | 0x0140);

@@ -1095,6 +1088,7 @@

// wm8987_write(codec, WM8987_ROUT2V, 0x0100);

wm8987_write(codec, WM8987_ROUT2V, 0x17a);

+

wm8987_add_controls(codec);

wm8987_add_widgets(codec);

ret = snd_soc_register_card(socdev);

@@ -1310,8 +1304,7 @@

struct snd_soc_codec *codec = socdev->codec;

if (codec->control_data)

- wm8987_set_bias_level(codec, SND_SOC_BIAS_OFF);

-

+ wm8987_dapm_event(codec, SNDRV_CTL_POWER_D3cold);

run_delayed_work(&codec->delayed_work);

snd_soc_free_pcms(socdev);

snd_soc_dapm_free(socdev);

ps:

Please check s3c64xx-iis driver code ,if it is not the same as smartq5/7 kernel 2.6.24 code ,it will caused some codec work not ok!