diff options
author | UK KIM <w0806.kim@samsung.com> | 2010-10-06 11:27:27 -0700 |
---|---|---|
committer | Arve Hjønnevåg <arve@android.com> | 2011-11-17 17:47:03 -0800 |
commit | 0bd74fc36b34517f24e86da6f2752055205afedc (patch) | |
tree | ccac865ab5525bc3b853666257526d51be0ca04a /sound/soc | |
parent | 143c394e0ddb158db56f37ca237d282ee8951200 (diff) | |
download | kernel_samsung_crespo-0bd74fc36b34517f24e86da6f2752055205afedc.zip kernel_samsung_crespo-0bd74fc36b34517f24e86da6f2752055205afedc.tar.gz kernel_samsung_crespo-0bd74fc36b34517f24e86da6f2752055205afedc.tar.bz2 |
S5PC11X: SOUND: fix pop noise issue
if clock and interface is set on status of amp opened, pop noise occurs.
codec driver works by PCM Stream.
strange value name was changed from old base code.
Signed-off-by: UK KIM <w0806.kim@samsung.com>
Change-Id: Ia88b6b79fcc82900bb5411bf9bc786afe6b01f42
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/codecs/wm8994_herring.c | 19 | ||||
-rwxr-xr-x | sound/soc/codecs/wm8994_samsung.c | 98 | ||||
-rwxr-xr-x | sound/soc/codecs/wm8994_samsung.h | 15 |
3 files changed, 88 insertions, 44 deletions
diff --git a/sound/soc/codecs/wm8994_herring.c b/sound/soc/codecs/wm8994_herring.c index 27637a5..18df501 100644 --- a/sound/soc/codecs/wm8994_herring.c +++ b/sound/soc/codecs/wm8994_herring.c @@ -487,6 +487,20 @@ void audio_ctrl_mic_bias_gpio(struct wm8994_platform_data *pdata, int enable) } } +static int wm8994_earsel_control(struct wm8994_platform_data *pdata, int en) +{ + + if (!pdata) { + pr_err("failed to control wm8994 ear selection\n"); + return -EINVAL; + } + + gpio_set_value(pdata->ear_sel, en); + + return 0; + +} + /* Audio Routing routines for the universal board..wm8994 codec*/ void wm8994_disable_playback_path(struct snd_soc_codec *codec, enum audio_path path) @@ -1108,6 +1122,8 @@ void wm8994_set_playback_headset(struct snd_soc_codec *codec) DEBUG_LOG(""); + wm8994_earsel_control(wm8994->pdata, 0); + /* Enable the Timeslot0 to DAC1L */ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING); val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK); @@ -1394,6 +1410,8 @@ void wm8994_set_playback_speaker_headset(struct snd_soc_codec *codec) u8 nservo4low = 0; u8 nservo4high = 0; + wm8994_earsel_control(wm8994->pdata, 0); + /* Enable the Timeslot0 to DAC1L */ val = wm8994_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING); val &= ~(WM8994_AIF1DAC1L_TO_DAC1L_MASK); @@ -1813,6 +1831,7 @@ void wm8994_set_voicecall_headset(struct snd_soc_codec *codec) DEBUG_LOG(""); audio_ctrl_mic_bias_gpio(wm8994->pdata, 1); + wm8994_earsel_control(wm8994->pdata, 1); wm8994_set_voicecall_common_setting(codec); diff --git a/sound/soc/codecs/wm8994_samsung.c b/sound/soc/codecs/wm8994_samsung.c index 6bea596..b098165 100755 --- a/sound/soc/codecs/wm8994_samsung.c +++ b/sound/soc/codecs/wm8994_samsung.c @@ -294,6 +294,8 @@ static int wm8994_set_mic_path(struct snd_kcontrol *kcontrol, DEBUG_LOG(""); + wm8994->codec_state |= CAPTURE_ACTIVE; + if (ucontrol->value.integer.value[0] == 0) wm8994->rec_path = MAIN; else if (ucontrol->value.integer.value[0] == 1) @@ -327,7 +329,7 @@ static int wm8994_set_path(struct snd_kcontrol *kcontrol, struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct wm8994_priv *wm8994 = codec->drvdata; struct soc_enum *mc = (struct soc_enum *)kcontrol->private_value; - + int val; int path_num = ucontrol->value.integer.value[0]; if (strcmp(mc->texts[path_num], playback_path[path_num])) { @@ -350,17 +352,17 @@ static int wm8994_set_path(struct snd_kcontrol *kcontrol, case SPK_HP: case BT: DEBUG_LOG("routing to %s\n", mc->texts[path_num]); - wm8994->ringtone_active = DEACTIVE; + wm8994->ringtone_active = RING_OFF; break; case RING_SPK: case RING_HP: DEBUG_LOG("routing to %s\n", mc->texts[path_num]); - wm8994->ringtone_active = ACTIVE; + wm8994->ringtone_active = RING_ON; path_num -= 4; break; case RING_SPK_HP: DEBUG_LOG("routing to %s\n", mc->texts[path_num]); - wm8994->ringtone_active = ACTIVE; + wm8994->ringtone_active = RING_ON; path_num -= 3; break; default: @@ -369,8 +371,17 @@ static int wm8994_set_path(struct snd_kcontrol *kcontrol, break; } + wm8994->codec_state |= PLAYBACK_ACTIVE; + + if (wm8994->codec_state & CALL_ACTIVE) { + wm8994->codec_state &= ~(CALL_ACTIVE); + + val = wm8994_read(codec, WM8994_CLOCKING_1); + val &= ~(WM8994_DSP_FS2CLK_ENA_MASK | WM8994_SYSCLK_SRC_MASK); + wm8994_write(codec, WM8994_CLOCKING_1, val); + } + wm8994->cur_path = path_num; - wm8994->call_state = DISCONNECT; wm8994->universal_playback_path[wm8994->cur_path] (codec); return 0; @@ -417,9 +428,10 @@ static int wm8994_set_voice_path(struct snd_kcontrol *kcontrol, break; } - if (wm8994->cur_path != path_num || wm8994->call_state == DISCONNECT) { + if (wm8994->cur_path != path_num || + !(wm8994->codec_state & CALL_ACTIVE)) { + wm8994->codec_state |= CALL_ACTIVE; wm8994->cur_path = path_num; - wm8994->call_state = CONNECT; wm8994->universal_voicecall_path[wm8994->cur_path] (codec); } else { int val; @@ -578,6 +590,11 @@ static int configure_clock(struct snd_soc_codec *codec) DEBUG_LOG(""); + if (wm8994->codec_state != DEACTIVE) { + DEBUG_LOG("Codec is already actvied. Skip clock setting."); + return 0; + } + reg = wm8994_read(codec, WM8994_AIF1_CLOCKING_1); reg &= ~WM8994_AIF1CLK_ENA; reg &= ~WM8994_AIF1CLK_SRC_MASK; @@ -1077,9 +1094,10 @@ static int wm8994_startup(struct snd_pcm_substream *substream, struct wm8994_priv *wm8994 = codec->drvdata; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - wm8994->play_en_dis = 1; + wm8994->stream_state |= PCM_STREAM_PLAYBACK; else - wm8994->rec_en_dis = 1; + wm8994->stream_state |= PCM_STREAM_CAPTURE; + if (wm8994->power_state == CODEC_OFF) { wm8994->power_state = CODEC_ON; @@ -1105,49 +1123,45 @@ static void wm8994_shutdown(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = codec_dai->codec; struct wm8994_priv *wm8994 = codec->drvdata; - DEBUG_LOG("%s.., wm8994->call_state = %d, current path = %d", - __func__, wm8994->call_state, wm8994->cur_path); + DEBUG_LOG("Stream_state = [0x%X], Codec State = [0x%X]", + wm8994->stream_state, wm8994->codec_state); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - wm8994->play_en_dis = 0; - DEBUG_LOG("..inside..%s..for PLAYBACK_STREAM!!", __func__); - if (wm8994->cur_path != OFF) - wm8994->cur_path = OFF; + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + wm8994->stream_state &= ~(PCM_STREAM_CAPTURE); + wm8994->codec_state &= ~(CAPTURE_ACTIVE); } else { - wm8994->rec_en_dis = 0; - DEBUG_LOG("..inside..%s..for CAPTURE_STREAM!!", __func__); - if (wm8994->mic_state == MIC_NO_USE && \ - wm8994->rec_path != MIC_OFF) - wm8994->rec_path = MIC_OFF; + wm8994->codec_state &= ~(PLAYBACK_ACTIVE); + wm8994->stream_state &= ~(PCM_STREAM_PLAYBACK); } - if (wm8994->call_state == DISCONNECT) { - if (!wm8994->play_en_dis && !wm8994->rec_en_dis) { - DEBUG_LOG("Turn off Codec!!"); - wm8994->pdata->set_mic_bias(false); - wm8994->power_state = CODEC_OFF; - wm8994_write(codec, WM8994_SOFTWARE_RESET, 0x0000); + if ((wm8994->codec_state == DEACTIVE) && + (wm8994->stream_state == PCM_STREAM_DEACTIVE)) { + DEBUG_LOG("Turn off Codec!!"); + wm8994->pdata->set_mic_bias(false); + wm8994->power_state = CODEC_OFF; + wm8994->cur_path = OFF; + wm8994->rec_path = MIC_OFF; + wm8994->ringtone_active = RING_OFF; + wm8994_write(codec, WM8994_SOFTWARE_RESET, 0x0000); return; - } } - DEBUG_LOG("Preserve codec state for call[%d].", - wm8994->call_state); + DEBUG_LOG("Preserve codec state = [0x%X], Stream State = [0x%X]", + wm8994->codec_state, wm8994->stream_state); if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - wm8994->universal_mic_path[MIC_OFF] (codec); + wm8994_disable_rec_path(codec); + wm8994->codec_state &= ~(CAPTURE_ACTIVE); } else { - if (wm8994->call_state == CONNECT) { + if (wm8994->codec_state & CALL_ACTIVE) { int val; + val = wm8994_read(codec, WM8994_AIF1_DAC1_FILTERS_1); val &= ~(WM8994_AIF1DAC1_MUTE_MASK); val |= (WM8994_AIF1DAC1_MUTE); wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, val); } } - - DEBUG_LOG("exiting ...%s...", __func__); - } static struct snd_soc_device *wm8994_socdev; @@ -1217,13 +1231,13 @@ static int wm8994_init(struct wm8994_priv *wm8994_private, wm8994->universal_voicecall_path = universal_wm8994_voicecall_paths; wm8994->universal_mic_path = universal_wm8994_mic_paths; wm8994->universal_clock_control = universal_clock_controls; + wm8994->stream_state = PCM_STREAM_DEACTIVE; wm8994->cur_path = OFF; wm8994->rec_path = MIC_OFF; - wm8994->call_state = DISCONNECT; wm8994->power_state = CODEC_OFF; + wm8994->recognition_active = REC_OFF; + wm8994->ringtone_active = RING_OFF; wm8994->mic_state = MIC_NO_USE; - wm8994->play_en_dis = 0; - wm8994->rec_en_dis = 0; wm8994->pdata = pdata; wm8994->universal_clock_control(codec, CODEC_ON); @@ -1456,9 +1470,11 @@ static int wm8994_suspend(struct platform_device *pdev, pm_message_t msg) struct snd_soc_codec *codec = wm8994_codec; struct wm8994_priv *wm8994 = codec->drvdata; - DEBUG_LOG("%s..", __func__); + DEBUG_LOG("Codec State = [0x%X], Stream State = [0x%X]", + wm8994->codec_state, wm8994->stream_state); - if (wm8994->call_state == DISCONNECT && wm8994->cur_path == OFF) { + if (wm8994->codec_state == DEACTIVE && + wm8994->stream_state == PCM_STREAM_DEACTIVE) { wm8994->power_state = OFF; wm8994_write(codec, WM8994_SOFTWARE_RESET, 0x0000); wm8994_ldo_control(wm8994->pdata, 0); @@ -1477,7 +1493,7 @@ static int wm8994_resume(struct platform_device *pdev) DEBUG_LOG_ERR("------WM8994 Revision = [%d]-------", wm8994->hw_version); - if (wm8994->call_state == DISCONNECT && wm8994->cur_path == OFF) { + if (wm8994->power_state == CODEC_OFF) { /* Turn on sequence by recommend Wolfson.*/ wm8994_ldo_control(wm8994->pdata, 1); wm8994->universal_clock_control(codec, CODEC_ON); diff --git a/sound/soc/codecs/wm8994_samsung.h b/sound/soc/codecs/wm8994_samsung.h index 37ca0b0..caf1f9c 100755 --- a/sound/soc/codecs/wm8994_samsung.h +++ b/sound/soc/codecs/wm8994_samsung.h @@ -34,6 +34,15 @@ extern struct snd_soc_dai wm8994_dai; #define AUDIO_COMMON_DEBUG 0 +#define DEACTIVE 0x00 +#define PLAYBACK_ACTIVE 0x01 +#define CAPTURE_ACTIVE 0x02 +#define CALL_ACTIVE 0x04 + +#define PCM_STREAM_DEACTIVE 0x00 +#define PCM_STREAM_PLAYBACK 0x01 +#define PCM_STREAM_CAPTURE 0x02 + /* Codec Output Path BIT */ #define PLAYBACK_MODE 0x01 #define VOICECALL_MODE (0x01 << 1) @@ -77,7 +86,7 @@ enum mic_path {MAIN, SUB, BT_REC, MIC_OFF}; enum call_state {DISCONNECT, CONNECT}; enum power_state {CODEC_OFF, CODEC_ON }; enum mic_state {MIC_NO_USE, MIC_USE}; -enum ringtone_state {DEACTIVE, ACTIVE}; +enum ringtone_state {RING_OFF, RING_ON}; enum recognition {REC_OFF, REC_ON}; typedef void (*select_route)(struct snd_soc_codec *); @@ -99,6 +108,8 @@ struct wm8994_priv { unsigned int fs; unsigned int bclk; unsigned int hw_version; + unsigned int codec_state; + unsigned int stream_state; enum audio_path cur_path; enum mic_path rec_path; enum call_state call_state; @@ -110,8 +121,6 @@ struct wm8994_priv { select_route *universal_voicecall_path; select_mic_route *universal_mic_path; select_clock_control universal_clock_control; - bool play_en_dis; - bool rec_en_dis; struct wm8994_platform_data *pdata; struct clk *codec_clk; }; |