diff options
author | Uk Kim <w0806.kim@samsung.com> | 2011-02-01 12:53:58 +0900 |
---|---|---|
committer | Arve Hjønnevåg <arve@android.com> | 2011-11-17 17:53:05 -0800 |
commit | fb36486113238c3a9ce37392626ef925cce078e6 (patch) | |
tree | b8b28a4e41f513a5bbf1d1cd211a0fad24118b8a /sound | |
parent | fd782c6d904f38fc8dbff87373b37fe2fcef5294 (diff) | |
download | kernel_samsung_crespo-fb36486113238c3a9ce37392626ef925cce078e6.zip kernel_samsung_crespo-fb36486113238c3a9ce37392626ef925cce078e6.tar.gz kernel_samsung_crespo-fb36486113238c3a9ce37392626ef925cce078e6.tar.bz2 |
ASOC : add tty device of each tty mode.
supports VCO, HCO, FULL mode of TTY during call.
Change-Id: If56d0c3da20377c59adc8681769e443f35da045c
Signed-off-by: Uk Kim <w0806.kim@samsung.com>
Diffstat (limited to 'sound')
-rwxr-xr-x | sound/soc/codecs/wm8994_herring.c | 552 | ||||
-rwxr-xr-x | sound/soc/codecs/wm8994_samsung.c | 24 | ||||
-rwxr-xr-x | sound/soc/codecs/wm8994_samsung.h | 13 |
3 files changed, 561 insertions, 28 deletions
diff --git a/sound/soc/codecs/wm8994_herring.c b/sound/soc/codecs/wm8994_herring.c index 74caf44..491b58b 100755 --- a/sound/soc/codecs/wm8994_herring.c +++ b/sound/soc/codecs/wm8994_herring.c @@ -409,8 +409,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 - } - + }, { /* TTY_VCO */ + .mode = VOICECALL_TTY_VCO, + .reg = WM8994_LEFT_LINE_INPUT_1_2_VOLUME, /* 18h */ + .mask = WM8994_IN1L_VOL_MASK, + .gain = WM8994_IN1L_VU | 0x15 /* +10.5dB */ + }, { + .mode = VOICECALL_TTY_VCO, + .reg = WM8994_INPUT_MIXER_3, /* 29h */ + .mask = WM8994_IN1L_MIXINL_VOL_MASK | WM8994_MIXOUTL_MIXINL_VOL_MASK, + .gain = 0x0 + }, { /* TTY_HCO */ + .mode = VOICECALL_TTY_HCO, + .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */ + .mask = WM8994_IN1R_VOL_MASK, + .gain = WM8994_IN1R_VU | 0x04 + }, { + .mode = VOICECALL_TTY_HCO, + .reg = WM8994_INPUT_MIXER_4, /* 2Ah */ + .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK, + .gain = 0x0 + }, { /* TTY_FULL */ + .mode = VOICECALL_TTY_FULL, + .reg = WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, /* 1Ah */ + .mask = WM8994_IN1R_VOL_MASK, + .gain = WM8994_IN1R_VU | 0x04 + }, { + .mode = VOICECALL_TTY_FULL, + .reg = WM8994_INPUT_MIXER_4, /* 2Ah */ + .mask = WM8994_IN1R_MIXINR_VOL_MASK | WM8994_MIXOUTR_MIXINR_VOL_MASK, + .gain = 0x0 + }, }; struct gain_info_t recording_gain_table[RECORDING_GAIN_NUM] = { @@ -591,7 +620,7 @@ struct gain_info_t gain_code_table[GAIN_CODE_NUM] = { .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */ }, {/* HP_NO_MIC */ .mode = PLAYBACK_HP_NO_MIC | PLAYBACK_MODE | GAIN_DIVISION_BIT_1, - .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */ + .reg = WM8994_LEFT_OUTPUT_VOLUME, /* 1Ch */ .mask = WM8994_HPOUT1L_VOL_MASK, .gain = WM8994_HPOUT1_VU | 0x31 /* -8dB */ }, { @@ -649,29 +678,29 @@ struct gain_info_t gain_code_table[GAIN_CODE_NUM] = { static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op) { - unsigned int reg; - int count = 0; - unsigned int val, start; + unsigned int reg; + int count = 0; + unsigned int val, start; - val = op | WM8994_DCS_ENA_CHAN_0 | WM8994_DCS_ENA_CHAN_1; + val = op | WM8994_DCS_ENA_CHAN_0 | WM8994_DCS_ENA_CHAN_1; - /* Trigger the command */ - snd_soc_write(codec, WM8994_DC_SERVO_1, val); + /* Trigger the command */ + snd_soc_write(codec, WM8994_DC_SERVO_1, val); start = jiffies; - pr_debug("Waiting for DC servo...\n"); + pr_debug("Waiting for DC servo...\n"); - do { - count++; - msleep(1); - reg = snd_soc_read(codec, WM8994_DC_SERVO_1); - pr_debug("DC servo: %x\n", reg); - } while (reg & op && count < 400); + do { + count++; + msleep(1); + reg = snd_soc_read(codec, WM8994_DC_SERVO_1); + pr_debug("DC servo: %x\n", reg); + } while (reg & op && count < 400); pr_info("DC servo took %dms\n", jiffies_to_msecs(jiffies - start)); - if (reg & op) - pr_err("Timed out waiting for DC Servo\n"); + if (reg & op) + pr_err("Timed out waiting for DC Servo\n"); } /* S5P_SLEEP_CONFIG must be controlled by codec if codec use XUSBTI */ @@ -2638,6 +2667,484 @@ void wm8994_set_voicecall_bluetooth(struct snd_soc_codec *codec) wm8994_write(codec, WM8994_AIF2_DAC_FILTERS_1, 0x0000); } +void wm8994_set_voicecall_tty_vco(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_TTY_VCO); + + /* 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_tty_hco(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(""); + + wm8994_earsel_control(wm8994->pdata, 1); + + wm8994_set_voicecall_common_setting(codec); + + /* Digital Path Enables and Unmutes */ + if (wm8994->hw_version == 3) { /* H/W Rev D */ + wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, + WM8994_ADC2_TO_DAC2L); + wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x0180); + wm8994_write(codec, WM8994_SIDETONE, 0x01C0); + } else { /* H/W Rev B */ + wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C); + wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, + WM8994_ADC1_TO_DAC2L); + wm8994_write(codec, WM8994_SIDETONE, 0x01C1); + } + + /* Analogue Input Configuration */ + val = (WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS | + WM8994_MIXINR_ENA | WM8994_IN1R_ENA); + wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val); + + val = wm8994_read(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME); + val &= ~(WM8994_IN1R_MUTE_MASK); + wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, val); + + val = wm8994_read(codec, WM8994_INPUT_MIXER_4); + val &= ~(WM8994_IN1R_TO_MIXINR_MASK); + val |= (WM8994_IN1R_TO_MIXINR); + wm8994_write(codec, WM8994_INPUT_MIXER_4, val); + + val = (WM8994_IN1RP_TO_IN1R | WM8994_IN1RN_TO_IN1R); + wm8994_write(codec, WM8994_INPUT_MIXER_2, val); + + /* 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); + + wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, + WM8994_AIF2ADCL_ENA | WM8994_ADCR_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, + WM8994_HPOUT2_ENA | WM8994_VMID_SEL_NORMAL | WM8994_BIAS_ENA); + + 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_HPOUT2_MIXER, WM8994_MIXOUTLVOL_TO_HPOUT2 | + WM8994_MIXOUTRVOL_TO_HPOUT2); + + wm8994_write(codec, WM8994_POWER_MANAGEMENT_3, + WM8994_MIXOUTLVOL_ENA | WM8994_MIXOUTRVOL_ENA | + WM8994_MIXOUTL_ENA | WM8994_MIXOUTR_ENA); + + 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); + + val = wm8994_read(codec, WM8994_HPOUT2_VOLUME); + val &= ~(WM8994_HPOUT2_MUTE_MASK); + wm8994_write(codec, WM8994_HPOUT2_VOLUME, val); + + wm8994_set_codec_gain(codec, VOICECALL_MODE, VOICECALL_TTY_HCO); + + /* 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_tty_full(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(""); + + wm8994_earsel_control(wm8994->pdata, 1); + + wm8994_set_voicecall_common_setting(codec); + + /* Digital Path Enables and Unmutes */ + if (wm8994->hw_version == 3) { /* H/W Rev D */ + wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, + WM8994_ADC2_TO_DAC2L); + wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x0180); + wm8994_write(codec, WM8994_SIDETONE, 0x01C0); + } else { /* H/W Rev B */ + wm8994_write(codec, WM8994_DAC2_MIXER_VOLUMES, 0x000C); + wm8994_write(codec, WM8994_DAC2_LEFT_MIXER_ROUTING, + WM8994_ADC1_TO_DAC2L); + wm8994_write(codec, WM8994_SIDETONE, 0x01C1); + } + + /* Analogue Input Configuration */ + val = (WM8994_TSHUT_ENA | WM8994_TSHUT_OPDIS | + WM8994_MIXINR_ENA | WM8994_IN1R_ENA); + wm8994_write(codec, WM8994_POWER_MANAGEMENT_2, val); + + val = wm8994_read(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME); + val &= ~(WM8994_IN1R_MUTE_MASK); + wm8994_write(codec, WM8994_RIGHT_LINE_INPUT_1_2_VOLUME, val); + + val = wm8994_read(codec, WM8994_INPUT_MIXER_4); + val &= ~(WM8994_IN1R_TO_MIXINR_MASK); + val |= (WM8994_IN1R_TO_MIXINR); + wm8994_write(codec, WM8994_INPUT_MIXER_4, val); + + val = (WM8994_IN1RP_TO_IN1R | WM8994_IN1RN_TO_IN1R); + wm8994_write(codec, WM8994_INPUT_MIXER_2, val); + + /* 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); + + wm8994_write(codec, WM8994_POWER_MANAGEMENT_4, 0x2001); + + 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_TTY_FULL); + + /* 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); + +} + int wm8994_set_codec_gain(struct snd_soc_codec *codec, u16 mode, u16 device) { struct wm8994_priv *wm8994 = codec->drvdata; @@ -2704,6 +3211,15 @@ int wm8994_set_codec_gain(struct snd_soc_codec *codec, u16 mode, u16 device) case VOICECALL_BT: gain_set_bits |= VOICECALL_BT; break; + case VOICECALL_TTY_VCO: + gain_set_bits |= (VOICECALL_HP_NO_MIC | VOICECALL_TTY_VCO); + break; + case VOICECALL_TTY_HCO: + gain_set_bits |= (VOICECALL_RCV | VOICECALL_TTY_HCO); + break; + case VOICECALL_TTY_FULL: + gain_set_bits |= (VOICECALL_HP | VOICECALL_TTY_FULL); + break; default: pr_err("voicemode gain flag is wrong\n"); } diff --git a/sound/soc/codecs/wm8994_samsung.c b/sound/soc/codecs/wm8994_samsung.c index 32b6163..0fecae5 100755 --- a/sound/soc/codecs/wm8994_samsung.c +++ b/sound/soc/codecs/wm8994_samsung.c @@ -123,7 +123,9 @@ select_route universal_wm8994_playback_paths[] = { select_route universal_wm8994_voicecall_paths[] = { wm8994_disable_path, wm8994_set_voicecall_receiver, wm8994_set_voicecall_speaker, wm8994_set_voicecall_headset, - wm8994_set_voicecall_headphone, wm8994_set_voicecall_bluetooth + wm8994_set_voicecall_headphone, wm8994_set_voicecall_bluetooth, + wm8994_set_voicecall_tty_vco, wm8994_set_voicecall_tty_hco, + wm8994_set_voicecall_tty_full, }; select_mic_route universal_wm8994_mic_paths[] = { @@ -273,13 +275,14 @@ static int wm899x_inpga_put_volsw_vu(struct snd_kcontrol *kcontrol, * Implementation of sound path */ #define MAX_PLAYBACK_PATHS 10 -#define MAX_VOICECALL_PATH 5 +#define MAX_VOICECALL_PATH 8 static const char *playback_path[] = { "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", - "HP_NO_MIC", "BT" }; + "HP_NO_MIC", "BT", "TTY_VCO", + "TTY_HCO", "TTY_FULL"}; static const char *mic_path[] = { "Main Mic", "Hands Free Mic", "BT Sco Mic", "MIC OFF" }; static const char *input_source_state[] = { "Default", "Voice Recognition", @@ -431,14 +434,17 @@ static int wm8994_set_voice_path(struct snd_kcontrol *kcontrol, } switch (path_num) { - case OFF: + case CALL_OFF: DEBUG_LOG("Switching off output path\n"); break; - case RCV: - case SPK: - case HP: - case HP_NO_MIC: - case BT: + case CALL_RCV: + case CALL_SPK: + case CALL_HP: + case CALL_HP_NO_MIC: + case CALL_BT: + case CALL_TTY_VCO: + case CALL_TTY_HCO: + case CALL_TTY_FULL: DEBUG_LOG("routing voice path to %s\n", mc->texts[path_num]); break; default: diff --git a/sound/soc/codecs/wm8994_samsung.h b/sound/soc/codecs/wm8994_samsung.h index f0b92e3..0950b86 100755 --- a/sound/soc/codecs/wm8994_samsung.h +++ b/sound/soc/codecs/wm8994_samsung.h @@ -81,6 +81,9 @@ Codec Output Path BIT #define VOICECALL_HP (0x01 << 3) #define VOICECALL_HP_NO_MIC (0x01 << 4) #define VOICECALL_BT (0x01 << 5) +#define VOICECALL_TTY_VCO (0x01 << 6) +#define VOICECALL_TTY_HCO (0x01 << 7) +#define VOICECALL_TTY_FULL (0x01 << 8) #define RECORDING_MAIN (0x01 << 1) #define RECORDING_HP (0x01 << 2) @@ -96,7 +99,7 @@ Codec Output Path BIT #define RECORDING_VC_BT (0x01 << 12) #define PLAYBACK_GAIN_NUM 43 -#define VOICECALL_GAIN_NUM 32 +#define VOICECALL_GAIN_NUM 38 #define RECORDING_GAIN_NUM 32 #define GAIN_CODE_NUM 13 /* @@ -106,6 +109,11 @@ enum audio_path { OFF, RCV, SPK, HP, HP_NO_MIC, BT, SPK_HP, RING_SPK, RING_HP, RING_NO_MIC, RING_SPK_HP }; +enum call_path { + CALL_OFF, CALL_RCV, CALL_SPK, CALL_HP, + CALL_HP_NO_MIC, CALL_BT, CALL_TTY_VCO, + CALL_TTY_HCO, CALL_TTY_FULL +}; enum mic_path {MAIN, SUB, BT_REC, MIC_OFF}; enum power_state {CODEC_OFF, CODEC_ON }; enum ringtone_state {RING_OFF, RING_ON}; @@ -193,6 +201,9 @@ 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); +void wm8994_set_voicecall_tty_vco(struct snd_soc_codec *codec); +void wm8994_set_voicecall_tty_hco(struct snd_soc_codec *codec); +void wm8994_set_voicecall_tty_full(struct snd_soc_codec *codec); int wm8994_set_codec_gain(struct snd_soc_codec *codec, u16 mode, u16 device); extern int gain_code_check(void); #endif |