type == RK616_CODEC_CAPTURE ? "capture" : "",
type == RK616_CODEC_INCALL ? "incall" : "");
- if (type == RK616_CODEC_PLAYBACK) {
- // mute output for pop noise
+ // mute output for pop noise
+ if (type == RK616_CODEC_PLAYBACK ||
+ type == RK616_CODEC_INCALL ||
+ type == RK616_CODEC_ALL) {
rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW);
rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_LOW);
+ }
+ if (type == RK616_CODEC_PLAYBACK) {
for (i = 0; i < RK616_CODEC_PLAYBACK_POWER_UP_LIST_LEN; i++) {
snd_soc_write(codec, playback_power_up_list[i].reg,
playback_power_up_list[i].value);
capture_power_up_list[i].value);
}
} else if (type == RK616_CODEC_INCALL) {
+ //delay for MOS or AMP mute, or it will get some pop noise.
+ mdelay(SPK_AMP_DELAY);
+
snd_soc_update_bits(codec, RK616_PGA_AGC_CTL,
0x0f, 0x09); //set for capture pop noise
snd_soc_update_bits(codec, RK616_MIXINL_CTL,
- RK616_MIL_F_IN3L | RK616_MIL_MUTE, 0); //IN3L to MIXINL, unmute IN3L
+ RK616_MIL_F_IN3L | RK616_MIL_MUTE | RK616_MIL_PWRD,
+ 0); //IN3L to MIXINL, unmute IN3L
snd_soc_update_bits(codec, RK616_MIXINL_VOL2,
- RK616_MIL_F_IN3L_VOL_MASK, 7); //IN3L to MIXINL vol
+ RK616_MIL_F_IN3L_VOL_MASK, 0); //IN3L to MIXINL vol
snd_soc_update_bits(codec, RK616_PGAL_CTL,
- 0xff, 0x9f); //PU unmute PGAL,PGAL vol
+ 0xff, 15); //PU unmute PGAL,PGAL vol
snd_soc_update_bits(codec, RK616_HPMIX_CTL,
RK616_HML_F_PGAL | RK616_HMR_F_PGAL, 0);
}
// mute output for pop noise
if (type == RK616_CODEC_PLAYBACK ||
+ type == RK616_CODEC_INCALL ||
type == RK616_CODEC_ALL) {
rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW);
rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_LOW);
}
if (type == RK616_CODEC_INCALL || type == RK616_CODEC_ALL) {
+ //delay for MOS or AMP mute, or it will get some pop noise.
+ mdelay(SPK_AMP_DELAY);
+
//close incall route
snd_soc_update_bits(codec, RK616_HPMIX_CTL,
RK616_HML_F_PGAL | RK616_HMR_F_PGAL,
snd_soc_update_bits(codec, RK616_PGA_AGC_CTL,
0x0f, 0x0c);
snd_soc_update_bits(codec, RK616_MIXINL_CTL,
- RK616_MIL_F_IN3L | RK616_MIL_MUTE,
- RK616_MIL_F_IN3L | RK616_MIL_MUTE);
+ RK616_MIL_F_IN3L | RK616_MIL_MUTE | RK616_MIL_PWRD,
+ RK616_MIL_F_IN3L | RK616_MIL_MUTE | RK616_MIL_PWRD);
snd_soc_update_bits(codec, RK616_MIXINL_VOL2,
- RK616_MIL_F_IN3L_VOL_MASK, 4);
+ RK616_MIL_F_IN3L_VOL_MASK, 0);
snd_soc_update_bits(codec, RK616_PGAL_CTL,
0xff, 0xcc);
}
static const char *rk616_voice_call_path_mode[] = {"OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT"};//0-5
+static const char *rk616_modem_input_sel[] = {"ON", "OFF"};
+
static const SOC_ENUM_SINGLE_DECL(rk616_playback_path_type, 0, 0, rk616_playback_path_mode);
static const SOC_ENUM_SINGLE_DECL(rk616_capture_path_type, 0, 0, rk616_capture_path_mode);
static const SOC_ENUM_SINGLE_DECL(rk616_voice_call_path_type, 0, 0, rk616_voice_call_path_mode);
+static const struct soc_enum rk616_modem_input_enum =
+ SOC_ENUM_SINGLE(RK616_PGAL_CTL, RK616_PGA_MUTE_SFT, 2, rk616_modem_input_sel);
+
static int rk616_playback_path_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
break;
case SPK_PATH:
case RING_SPK:
+ rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_LOW);
+
if (pre_path == OFF)
rk616_codec_power_up(RK616_CODEC_PLAYBACK);
case HP_NO_MIC:
case RING_HP:
case RING_HP_NO_MIC:
+ rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW);
+
if (pre_path == OFF)
rk616_codec_power_up(RK616_CODEC_PLAYBACK);
rk616->voice_call_path, pre_path);
//open playback route for incall route and keytone
- if (pre_path == OFF) {
- if (rk616->playback_path != OFF) {
- //mute output for incall route pop nosie
- rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW);
- rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_LOW);
- if (rk616->voice_call_path == SPK_PATH)
- mdelay(SPK_AMP_DELAY);
- else if (rk616->voice_call_path == HP_PATH ||
- rk616->voice_call_path == HP_NO_MIC)
- mdelay(HP_MOS_DELAY);
- } else
+ if (pre_path == OFF && rk616->playback_path == OFF) {
rk616_codec_power_up(RK616_CODEC_PLAYBACK);
}
case OFF:
if (pre_path != RCV &&
pre_path != BT) {
- //mute output for incall route pop nosie
- rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW);
- rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_LOW);
- if (pre_path == SPK_PATH)
- mdelay(SPK_AMP_DELAY);
- else if (pre_path == HP_PATH ||
- pre_path == HP_NO_MIC)
- mdelay(HP_MOS_DELAY);
-
rk616_codec_power_down(RK616_CODEC_INCALL);
}
//rcv is controled by modem, so close incall route
if (pre_path != OFF &&
pre_path != BT) {
- //mute output for incall route pop nosie
- rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW);
- rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_LOW);
- if (pre_path == SPK_PATH)
- mdelay(SPK_AMP_DELAY);
- else if (pre_path == HP_PATH ||
- pre_path == HP_NO_MIC)
- mdelay(HP_MOS_DELAY);
-
rk616_codec_power_down(RK616_CODEC_INCALL);
}
//BT is controled by modem, so close incall route
if (pre_path != OFF &&
pre_path != RCV) {
- //mute output for incall route pop nosie
- rk616_set_gpio(RK616_CODEC_SET_SPK, GPIO_LOW);
- rk616_set_gpio(RK616_CODEC_SET_HP, GPIO_LOW);
-
- if (rk616->voice_call_path == SPK_PATH)
- mdelay(SPK_AMP_DELAY);
- else if (rk616->voice_call_path == HP_PATH ||
- rk616->voice_call_path == HP_NO_MIC)
- mdelay(HP_MOS_DELAY);
rk616_codec_power_down(RK616_CODEC_INCALL);
}
SOC_ENUM_EXT("Voice Call Path", rk616_voice_call_path_type,
rk616_voice_call_path_get, rk616_voice_call_path_put),
+
+ /*
+ * When modem connecting, it will make some pop noise.
+ * So, add this control for modem. Modem will set 'OFF'
+ * before incall connected, and set 'ON' after connected.
+ */
+ SOC_ENUM("Modem Input Enable", rk616_modem_input_enum),
};
static int rk616_dacl_event(struct snd_soc_dapm_widget *w,