diff options
author | UK KIM <w0806.kim@samsung.com> | 2010-10-21 16:12:47 -0700 |
---|---|---|
committer | Arve Hjønnevåg <arve@android.com> | 2011-11-17 17:51:39 -0800 |
commit | e0d2daab7aa7fad26e8d38673fadd73d8b662882 (patch) | |
tree | 4da4553b85a623a20e837e35fbb86af8702015a6 /sound | |
parent | d583fb47af4da3c57e180bcf15c45515f4c00d1e (diff) | |
download | kernel_samsung_crespo-e0d2daab7aa7fad26e8d38673fadd73d8b662882.zip kernel_samsung_crespo-e0d2daab7aa7fad26e8d38673fadd73d8b662882.tar.gz kernel_samsung_crespo-e0d2daab7aa7fad26e8d38673fadd73d8b662882.tar.bz2 |
S5PC11X: SOUND: add headphone device for output and input stream
must distinguish headset and headphone device for built-in mic
output device is seperated but use same path.
Change-Id: I45cc27c74d0eb3505e1b5adb1ba52690261ae0f3
Signed-off-by: UK KIM <w0806.kim@samsung.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/codecs/wm8994_herring.c | 205 | ||||
-rwxr-xr-x | sound/soc/codecs/wm8994_samsung.c | 27 | ||||
-rwxr-xr-x | sound/soc/codecs/wm8994_samsung.h | 12 |
3 files changed, 227 insertions, 17 deletions
diff --git a/sound/soc/codecs/wm8994_herring.c b/sound/soc/codecs/wm8994_herring.c index 0650755..a2243d9 100644 --- a/sound/soc/codecs/wm8994_herring.c +++ b/sound/soc/codecs/wm8994_herring.c @@ -359,7 +359,37 @@ struct gain_info_t voicecall_gain_table[VOICECALL_GAIN_NUM] = { .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */ .mask = WM8994_HPOUT1R_VOL_MASK, .gain = WM8994_HPOUT1_VU | 0x30 - }, + }, { /* HP_NO_MIC */ + .mode = VOICECALL_HP_NO_MIC, + .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */ + .mask = WM8994_IN1L_VOL_MASK, + .gain = WM8994_IN1L_VU | 0x18 + }, { + .mode = VOICECALL_HP_NO_MIC, + .reg = WM8994_INPUT_MIXER_3, /* 29h */ + .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK, + .gain = 0x10 + }, { + .mode = VOICECALL_HP_NO_MIC, + .reg = WM8994_LEFT_OPGA_VOLUME, /* 20h */ + .mask = WM8994_MIXOUTL_VOL_MASK, + .gain = WM8994_MIXOUT_VU | 0x39 + }, { + .mode = VOICECALL_HP_NO_MIC, + .reg = WM8994_RIGHT_OPGA_VOLUME, /* 21h */ + .mask = WM8994_MIXOUTR_VOL_MASK, + .gain = WM8994_MIXOUT_VU | 0x39 + }, { + .mode = VOICECALL_HP_NO_MIC, + .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */ + .mask = WM8994_HPOUT1L_VOL_MASK, + .gain = WM8994_HPOUT1_VU | 0x30 + }, { + .mode = VOICECALL_HP_NO_MIC, + .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */ + .mask = WM8994_HPOUT1R_VOL_MASK, + .gain = WM8994_HPOUT1_VU | 0x30 + } }; @@ -478,6 +508,21 @@ struct gain_info_t gain_code_table[VOICECALL_GAIN_NUM] = { .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */ .mask = WM8994_HPOUT1R_VOL_MASK, .gain = WM8994_HPOUT1_VU | 0x33 + }, {/* HP_NO_MIC */ + .mode = VOICECALL_HP_NO_MIC | GAIN_DIVISION_BIT, + .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */ + .mask = WM8994_IN1L_VOL_MASK, + .gain = WM8994_IN1L_VU | 0x18 + }, { + .mode = VOICECALL_HP_NO_MIC | GAIN_DIVISION_BIT, + .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */ + .mask = WM8994_HPOUT1L_VOL_MASK, + .gain = WM8994_HPOUT1_VU | 0x33 + }, { + .mode = VOICECALL_HP_NO_MIC | GAIN_DIVISION_BIT, + .reg = WM8994_RIGHT_OUTPUT_VOLUME, /* 1Dh */ + .mask = WM8994_HPOUT1R_VOL_MASK, + .gain = WM8994_HPOUT1_VU | 0x33 }, }; @@ -619,6 +664,7 @@ void wm8994_disable_path(struct snd_soc_codec *codec) break; case HP: + case HP_NO_MIC: val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME); val &= ~(0x02C0); val |= 0x02C0; @@ -2149,6 +2195,160 @@ void wm8994_set_voicecall_headset(struct snd_soc_codec *codec) } +void wm8994_set_voicecall_headphone(struct snd_soc_codec *codec) +{ + struct wm8994_priv *wm8994 = codec->drvdata; + + int val; + + u16 testreturn1 = 0; + u16 testreturn2 = 0; + u16 testlow1 = 0; + u16 testhigh1 = 0; + u8 testlow = 0; + u8 testhigh = 0; + + DEBUG_LOG(""); + audio_ctrl_mic_bias_gpio(wm8994->pdata, 1); + + wm8994_earsel_control(wm8994->pdata, 1); + + wm8994_set_voicecall_common_setting(codec); + + /* Digital Path Enables and Unmutes */ + wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C); + wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, + WM8994_ADC1_TO_DAC2L); + + /* Analogue Input Configuration */ + wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, + WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS | WM8994_MIXINL_ENA | + WM8994_IN1L_ENA); + + /* Unmute IN1L PGA, update volume */ + val = wm8994_read(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME); + val &= ~(WM8994_IN1L_MUTE_MASK); + wm8994_write(codec, WM8994_LEFT_LINE_INPUT_1_2_VOLUME, val); + + /* Unmute the PGA */ + val = wm8994_read(codec, WM8994_INPUT_MIXER_3); + val &= ~(WM8994_IN1L_TO_MIXINL_MASK); + val |= (WM8994_IN1L_TO_MIXINL); + wm8994_write(codec, WM8994_INPUT_MIXER_3, val); + + wm8994_write(codec, WM8994_INPUT_MIXER_2, + WM8994_IN1LP_TO_IN1L | WM8994_IN1LN_TO_IN1L); + + /* Unmute*/ + val = wm8994_read(codec, WM8994_LEFT_OPGA_VOLUME); + val &= ~(WM8994_MIXOUTL_MUTE_N_MASK); + val |= (WM8994_MIXOUTL_MUTE_N); + wm8994_write(codec, WM8994_LEFT_OPGA_VOLUME, val); + + val = wm8994_read(codec, WM8994_RIGHT_OPGA_VOLUME); + val &= ~(WM8994_MIXOUTR_MUTE_N_MASK); + val |= (WM8994_MIXOUTR_MUTE_N); + wm8994_write(codec, WM8994_RIGHT_OPGA_VOLUME, val); + + /* Digital Path Enables and Unmutes */ + wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, + WM8994_AIF2ADCL_ENA | WM8994_ADCL_ENA); + + val = wm8994_read(codec, 0x102); + val &= ~(0x0003); + val = 0x0003; + wm8994_write(codec, 0x102, val); + + val = wm8994_read(codec, 0x56); + val &= ~(0x0003); + val = 0x0003; + wm8994_write(codec, 0x56, val); + + val = wm8994_read(codec, 0x102); + val &= ~(0x0000); + val = 0x0000; + wm8994_write(codec, 0x102, val); + + val = wm8994_read(codec, WM8994_CLASS_W_1); + val &= ~(0x0005); + val |= 0x0005; + wm8994_write(codec, WM8994_CLASS_W_1, val); + + val = wm8994_read(codec, WM8994_LEFT_OUTPUT_VOLUME); + val &= ~(WM8994_HPOUT1L_MUTE_N_MASK); + val |= (WM8994_HPOUT1L_MUTE_N); + wm8994_write(codec, WM8994_LEFT_OUTPUT_VOLUME, val); + + val = wm8994_read(codec, WM8994_RIGHT_OUTPUT_VOLUME); + val &= ~(WM8994_HPOUT1R_MUTE_N_MASK); + val |= (WM8994_HPOUT1R_MUTE_N); + wm8994_write(codec, WM8994_RIGHT_OUTPUT_VOLUME, val); + + val = wm8994_read(codec, WM8994_DC_SERVO_2); + val &= ~(0x03E0); + val = 0x03E0; + wm8994_write(codec, WM8994_DC_SERVO_2, val); + + wm8994_write(codec, WM8994_POWER_MANAGEMENT_1, 0x0303); + + wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x0022); + wm8994_write(codec, WM8994_CHARGE_PUMP_1, 0x9F25); + + msleep(5); + + /* Analogue Output Configuration */ + wm8994_write(codec, WM8994_OUTPUT_MIXER_1, 0x0001); + wm8994_write(codec, WM8994_OUTPUT_MIXER_2, 0x0001); + + wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, 0x0030); + + wm8994_write(codec, WM8994_AIF2_CLOCKING_1, 0x0019); + + if (!wm8994->dc_servo[DCS_VOICE]) { + wait_for_dc_servo(codec, + WM8994_DCS_TRIG_SERIES_0 | + WM8994_DCS_TRIG_SERIES_1); + + testreturn1 = wm8994_read(codec, WM8994_DC_SERVO_4); + + testlow = (signed char)(testreturn1 & 0xff); + testhigh = (signed char)((testreturn1>>8) & 0xff); + + testlow1 = ((signed short)testlow - 5) & 0x00ff; + testhigh1 = (((signed short)(testhigh - 5)<<8) & 0xff00); + testreturn2 = testlow1|testhigh1; + } else { + testreturn2 = wm8994->dc_servo[DCS_VOICE]; + } + + wm8994_write(codec, WM8994_DC_SERVO_4, testreturn2); + + wait_for_dc_servo(codec, + WM8994_DCS_TRIG_DAC_WR_0 | WM8994_DCS_TRIG_DAC_WR_1); + + wm8994->dc_servo[DCS_VOICE] = testreturn2; + + wm8994_write(codec, WM8994_ANALOGUE_HP_1, 0x00EE); + + wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_HP_NO_MIC); + + /* Unmute DAC1 left */ + val = wm8994_read(codec, WM8994_DAC1_LEFT_VOLUME); + val &= ~(WM8994_DAC1L_MUTE_MASK); + wm8994_write(codec, WM8994_DAC1_LEFT_VOLUME, val); + + /* Unmute and volume ctrl RightDAC */ + val = wm8994_read(codec, WM8994_DAC1_RIGHT_VOLUME); + val &= ~(WM8994_DAC1R_MUTE_MASK); + wm8994_write(codec, WM8994_DAC1_RIGHT_VOLUME, val); + + wm8994_write(codec, WM8994_DAC2_LEFT_VOLUME, 0x01C0); + + wm8994_write(codec, WM8994_AIF1_DAC1_FILTERS_1, 0x0000); + wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000); + +} + void wm8994_set_voicecall_speaker(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = codec->drvdata; @@ -2365,6 +2565,9 @@ int wm8994_set_codec_gain(struct snd_soc_codec *codec, u16 mode, u16 device) case VOICECALL_HP: gain_set_bits |= VOICECALL_HP; break; + case VOICECALL_HP_NO_MIC: + gain_set_bits |= VOICECALL_HP_NO_MIC; + break; case VOICECALL_BT: gain_set_bits |= VOICECALL_BT; break; diff --git a/sound/soc/codecs/wm8994_samsung.c b/sound/soc/codecs/wm8994_samsung.c index c119f57..06b2af1 100755 --- a/sound/soc/codecs/wm8994_samsung.c +++ b/sound/soc/codecs/wm8994_samsung.c @@ -116,13 +116,14 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994); select_route universal_wm8994_playback_paths[] = { wm8994_disable_path, wm8994_set_playback_receiver, wm8994_set_playback_speaker, wm8994_set_playback_headset, - wm8994_set_playback_bluetooth, wm8994_set_playback_speaker_headset + wm8994_set_playback_headset, wm8994_set_playback_bluetooth, + wm8994_set_playback_speaker_headset }; select_route universal_wm8994_voicecall_paths[] = { wm8994_disable_path, wm8994_set_voicecall_receiver, wm8994_set_voicecall_speaker, wm8994_set_voicecall_headset, - wm8994_set_voicecall_bluetooth + wm8994_set_voicecall_headphone, wm8994_set_voicecall_bluetooth }; select_mic_route universal_wm8994_mic_paths[] = { @@ -271,13 +272,14 @@ static int wm899x_inpga_put_volsw_vu(struct snd_kcontrol *kcontrol, /* * Implementation of sound path */ -#define MAX_PLAYBACK_PATHS 8 -#define MAX_VOICECALL_PATH 4 +#define MAX_PLAYBACK_PATHS 10 +#define MAX_VOICECALL_PATH 5 static const char *playback_path[] = { - "OFF", "RCV", "SPK", "HP", "BT", "SPK_HP", - "RING_SPK", "RING_HP", "RING_SPK_HP" + "OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT", "SPK_HP", + "RING_SPK", "RING_HP", "RING_NO_MIC", "RING_SPK_HP" }; -static const char *voicecall_path[] = { "OFF", "RCV", "SPK", "HP", "BT" }; +static const char *voicecall_path[] = { "OFF", "RCV", "SPK", "HP", + "HP_NO_MIC", "BT" }; static const char *mic_path[] = { "Main Mic", "Hands Free Mic", "BT Sco Mic", "MIC OFF" }; static const char *recognition_state[] = { "RECOGNITION_OFF", @@ -309,7 +311,7 @@ static int wm8994_set_mic_path(struct snd_kcontrol *kcontrol, wm8994->rec_path = MAIN; break; case 1: - wm8994->rec_path = SUB; + wm8994->rec_path = SUB; break; case 2: wm8994->rec_path = BT_REC; @@ -360,21 +362,23 @@ static int wm8994_set_path(struct snd_kcontrol *kcontrol, case RCV: case SPK: case HP: - case SPK_HP: + case HP_NO_MIC: case BT: + case SPK_HP: DEBUG_LOG("routing to %s\n", mc->texts[path_num]); wm8994->ringtone_active = RING_OFF; break; case RING_SPK: case RING_HP: + case RING_NO_MIC: DEBUG_LOG("routing to %s\n", mc->texts[path_num]); wm8994->ringtone_active = RING_ON; - path_num -= 4; + path_num -= 5; break; case RING_SPK_HP: DEBUG_LOG("routing to %s\n", mc->texts[path_num]); wm8994->ringtone_active = RING_ON; - path_num -= 3; + path_num -= 4; break; default: DEBUG_LOG_ERR("audio path[%d] does not exists!!\n", path_num); @@ -430,6 +434,7 @@ static int wm8994_set_voice_path(struct snd_kcontrol *kcontrol, case RCV: case SPK: case HP: + case HP_NO_MIC: case BT: DEBUG_LOG("routing voice path to %s\n", mc->texts[path_num]); break; diff --git a/sound/soc/codecs/wm8994_samsung.h b/sound/soc/codecs/wm8994_samsung.h index 5a0f1cb..edf8f75 100755 --- a/sound/soc/codecs/wm8994_samsung.h +++ b/sound/soc/codecs/wm8994_samsung.h @@ -63,7 +63,8 @@ extern struct snd_soc_dai wm8994_dai; #define VOICECALL_RCV (0x01 << 1) #define VOICECALL_SPK (0x01 << 2) #define VOICECALL_HP (0x01 << 3) -#define VOICECALL_BT (0x01 << 4) +#define VOICECALL_HP_NO_MIC (0x01 << 4) +#define VOICECALL_BT (0x01 << 5) #define RECORDING_MAIN (0x01 << 1) #define RECORDING_HP (0x01 << 2) @@ -73,15 +74,15 @@ extern struct snd_soc_dai wm8994_dai; #define RECORDING_REC_BT (0x01 << 6) #define PLAYBACK_GAIN_NUM 39 -#define VOICECALL_GAIN_NUM 26 +#define VOICECALL_GAIN_NUM 32 #define RECORDING_GAIN_NUM 16 -#define GAIN_CODE_NUM 6 +#define GAIN_CODE_NUM 9 /* * Definitions of enum type */ enum audio_path { - OFF, RCV, SPK, HP, BT, SPK_HP, - RING_SPK, RING_HP, RING_SPK_HP + OFF, RCV, SPK, HP, HP_NO_MIC, BT, SPK_HP, + RING_SPK, RING_HP, RING_NO_MIC, RING_SPK_HP }; enum mic_path {MAIN, SUB, BT_REC, MIC_OFF}; enum power_state {CODEC_OFF, CODEC_ON }; @@ -167,6 +168,7 @@ void wm8994_set_playback_speaker_headset(struct snd_soc_codec *codec); void wm8994_set_voicecall_common_setting(struct snd_soc_codec *codec); void wm8994_set_voicecall_receiver(struct snd_soc_codec *codec); void wm8994_set_voicecall_headset(struct snd_soc_codec *codec); +void wm8994_set_voicecall_headphone(struct snd_soc_codec *codec); void wm8994_set_voicecall_speaker(struct snd_soc_codec *codec); void wm8994_set_voicecall_bluetooth(struct snd_soc_codec *codec); int wm8994_set_codec_gain(struct snd_soc_codec *codec, u16 mode, u16 device); |