From e0026d03942d38dd784baf4922badd980c692f89 Mon Sep 17 00:00:00 2001 From: Connor McAdams Date: Tue, 8 May 2018 13:20:12 -0400 Subject: ALSA: hda/ca0132: add ca0132_alt_set_vipsource Add function to set vipsource on cards that use_alt_controls. Different sequence. Also, add cvoice_switch_set at end of ca0132_select_in so that when switching between inputs cvoice state is maintained. Signed-off-by: Connor McAdams Reviewed-by: Takashi Sakamoto Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_ca0132.c | 74 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 394e604c3787..034fd12339f4 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -3938,6 +3938,9 @@ static void ca0132_unsol_hp_delayed(struct work_struct *work) static void ca0132_set_dmic(struct hda_codec *codec, int enable); static int ca0132_mic_boost_set(struct hda_codec *codec, long val); static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val); +static void resume_mic1(struct hda_codec *codec, unsigned int oldval); +static int stop_mic1(struct hda_codec *codec); +static int ca0132_cvoice_switch_set(struct hda_codec *codec); /* * Select the active VIP source @@ -3980,6 +3983,71 @@ static int ca0132_set_vipsource(struct hda_codec *codec, int val) return 1; } +static int ca0132_alt_set_vipsource(struct hda_codec *codec, int val) +{ + struct ca0132_spec *spec = codec->spec; + unsigned int tmp; + + if (spec->dsp_state != DSP_DOWNLOADED) + return 0; + + codec_dbg(codec, "%s\n", __func__); + + chipio_set_stream_control(codec, 0x03, 0); + chipio_set_stream_control(codec, 0x04, 0); + + /* if CrystalVoice is off, vipsource should be 0 */ + if (!spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID] || + (val == 0) || spec->in_enum_val == REAR_LINE_IN) { + codec_dbg(codec, "%s: off.", __func__); + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, 0); + + tmp = FLOAT_ZERO; + dspio_set_uint_param(codec, 0x80, 0x05, tmp); + + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000); + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000); + if (spec->quirk == QUIRK_R3DI) + chipio_set_conn_rate(codec, 0x0F, SR_96_000); + + + if (spec->in_enum_val == REAR_LINE_IN) + tmp = FLOAT_ZERO; + else { + if (spec->quirk == QUIRK_SBZ) + tmp = FLOAT_THREE; + else + tmp = FLOAT_ONE; + } + + dspio_set_uint_param(codec, 0x80, 0x00, tmp); + + } else { + codec_dbg(codec, "%s: on.", __func__); + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_16_000); + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_16_000); + if (spec->quirk == QUIRK_R3DI) + chipio_set_conn_rate(codec, 0x0F, SR_16_000); + + if (spec->effects_switch[VOICE_FOCUS - EFFECT_START_NID]) + tmp = FLOAT_TWO; + else + tmp = FLOAT_ONE; + dspio_set_uint_param(codec, 0x80, 0x00, tmp); + + tmp = FLOAT_ONE; + dspio_set_uint_param(codec, 0x80, 0x05, tmp); + + msleep(20); + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, val); + } + + chipio_set_stream_control(codec, 0x03, 1); + chipio_set_stream_control(codec, 0x04, 1); + + return 1; +} + /* * Select the active microphone. * If autodetect is enabled, mic will be selected based on jack detection. @@ -4142,6 +4210,7 @@ static int ca0132_alt_select_in(struct hda_codec *codec) } break; } + ca0132_cvoice_switch_set(codec); snd_hda_power_down_pm(codec); return 0; @@ -4355,7 +4424,10 @@ static int ca0132_cvoice_switch_set(struct hda_codec *codec) /* set correct vipsource */ oldval = stop_mic1(codec); - ret |= ca0132_set_vipsource(codec, 1); + if (spec->use_alt_functions) + ret |= ca0132_alt_set_vipsource(codec, 1); + else + ret |= ca0132_set_vipsource(codec, 1); resume_mic1(codec, oldval); return ret; } -- cgit