diff options
Diffstat (limited to 'sound')
-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; }; |