aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorUK KIM <w0806.kim@samsung.com>2010-10-21 16:12:47 -0700
committerArve Hjønnevåg <arve@android.com>2011-11-17 17:51:39 -0800
commite0d2daab7aa7fad26e8d38673fadd73d8b662882 (patch)
tree4da4553b85a623a20e837e35fbb86af8702015a6 /sound
parentd583fb47af4da3c57e180bcf15c45515f4c00d1e (diff)
downloadkernel_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.c205
-rwxr-xr-xsound/soc/codecs/wm8994_samsung.c27
-rwxr-xr-xsound/soc/codecs/wm8994_samsung.h12
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);