Loading sound/pci/hda/patch_via.c +75 −42 Original line number Diff line number Diff line Loading @@ -162,6 +162,7 @@ struct via_spec { const struct hda_input_mux *hp_mux; unsigned int hp_independent_mode; unsigned int hp_independent_mode_index; unsigned int can_smart51; unsigned int smart51_enabled; unsigned int dmic_enabled; unsigned int no_pin_power_ctl; Loading Loading @@ -544,7 +545,7 @@ static void via_auto_init_hp_out(struct hda_codec *codec) } } static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin); static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin); static void via_auto_init_analog_input(struct hda_codec *codec) { Loading @@ -555,7 +556,7 @@ static void via_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t nid = cfg->inputs[i].pin; if (spec->smart51_enabled && is_smart51_pins(spec, nid)) if (spec->smart51_enabled && is_smart51_pins(codec, nid)) ctl = PIN_OUT; else if (cfg->inputs[i].type == AUTO_PIN_MIC) ctl = PIN_VREF50; Loading @@ -580,7 +581,7 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, no_presence |= spec->no_pin_power_ctl; if (!no_presence) present = snd_hda_jack_detect(codec, nid); if ((spec->smart51_enabled && is_smart51_pins(spec, nid)) if ((spec->smart51_enabled && is_smart51_pins(codec, nid)) || ((no_presence || present) && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) { *affected_parm = AC_PWRST_D0; /* if it's connected */ Loading Loading @@ -919,16 +920,25 @@ static void mute_aa_path(struct hda_codec *codec, int mute) HDA_AMP_MUTE, val); } } static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin) static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin) { struct via_spec *spec = codec->spec; const struct auto_pin_cfg *cfg = &spec->autocfg; int i; for (i = 0; i < cfg->num_inputs; i++) { if (pin == cfg->inputs[i].pin) return cfg->inputs[i].type <= AUTO_PIN_LINE_IN; unsigned int defcfg; if (pin != cfg->inputs[i].pin) continue; if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) return false; defcfg = snd_hda_codec_get_pincfg(codec, pin); if (snd_hda_get_input_pin_attr(defcfg) < INPUT_PIN_ATTR_NORMAL) return false; return true; } return 0; return false; } static int via_smart51_info(struct snd_kcontrol *kcontrol, Loading @@ -952,13 +962,14 @@ static int via_smart51_get(struct snd_kcontrol *kcontrol, for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t nid = cfg->inputs[i].pin; int ctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) continue; unsigned int ctl; if (cfg->inputs[i].type == AUTO_PIN_MIC && spec->hp_independent_mode && spec->codec_type != VT1718S) continue; /* ignore FMic for independent HP */ if (!is_smart51_pins(codec, nid)) continue; ctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); if ((ctl & AC_PINCTL_IN_EN) && !(ctl & AC_PINCTL_OUT_EN)) on = 0; } Loading @@ -980,11 +991,11 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol, hda_nid_t nid = cfg->inputs[i].pin; unsigned int parm; if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) continue; if (cfg->inputs[i].type == AUTO_PIN_MIC && spec->hp_independent_mode && spec->codec_type != VT1718S) continue; /* don't retask FMic for independent HP */ if (!is_smart51_pins(codec, nid)) continue; parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); Loading @@ -997,23 +1008,6 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol, mute_aa_path(codec, 1); notify_aa_path_ctls(codec); } if (spec->codec_type == VT1718S) { snd_hda_codec_amp_stereo( codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_UNMUTE); } if (cfg->inputs[i].type == AUTO_PIN_MIC) { if (spec->codec_type == VT1708S || spec->codec_type == VT1716S) { /* input = index 1 (AOW3) */ snd_hda_codec_write( codec, nid, 0, AC_VERB_SET_CONNECT_SEL, 1); snd_hda_codec_amp_stereo( codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_UNMUTE); } } } spec->smart51_enabled = *ucontrol->value.integer.value; set_widgets_power_state(codec); Loading @@ -1029,16 +1023,15 @@ static const struct snd_kcontrol_new via_smart51_mixer = { .put = via_smart51_put, }; static int via_smart51_build(struct via_spec *spec) static int via_smart51_build(struct hda_codec *codec) { struct via_spec *spec = codec->spec; struct snd_kcontrol_new *knew; const struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t nid; int i; if (!cfg) return 0; if (cfg->line_outs > 2) if (!spec->can_smart51) return 0; knew = via_clone_control(spec, &via_smart51_mixer); Loading @@ -1047,7 +1040,7 @@ static int via_smart51_build(struct via_spec *spec) for (i = 0; i < cfg->num_inputs; i++) { nid = cfg->inputs[i].pin; if (cfg->inputs[i].type <= AUTO_PIN_LINE_IN) { if (is_smart51_pins(codec, nid)) { knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; break; } Loading Loading @@ -1943,15 +1936,37 @@ static int create_ch_ctls(struct hda_codec *codec, const char *pfx, static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, hda_nid_t nid); static void mangle_smart51(struct hda_codec *codec) { struct via_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; int i; for (i = 0; i < cfg->num_inputs; i++) { if (!is_smart51_pins(codec, cfg->inputs[i].pin)) continue; spec->can_smart51 = 1; cfg->line_out_pins[cfg->line_outs++] = cfg->inputs[i].pin; if (cfg->line_outs == 3) break; } } /* add playback controls from the parsed DAC table */ static int via_auto_create_multi_out_ctls(struct hda_codec *codec) { struct via_spec *spec = codec->spec; const struct auto_pin_cfg *cfg = &spec->autocfg; struct auto_pin_cfg *cfg = &spec->autocfg; static const char * const chname[4] = { "Front", "Surround", "C/LFE", "Side" }; int i, idx, err; int old_line_outs; /* check smart51 */ old_line_outs = cfg->line_outs; if (cfg->line_outs == 1) mangle_smart51(codec); for (i = 0; i < cfg->line_outs; i++) { hda_nid_t pin, dac; Loading Loading @@ -1991,6 +2006,8 @@ static int via_auto_create_multi_out_ctls(struct hda_codec *codec) return err; } cfg->line_outs = old_line_outs; return 0; } Loading Loading @@ -2246,7 +2263,10 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) if (spec->hp_mux) via_hp_build(codec); via_smart51_build(spec); err = via_smart51_build(codec); if (err < 0) return err; return 1; } Loading Loading @@ -2523,7 +2543,10 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) if (spec->hp_mux) via_hp_build(codec); via_smart51_build(spec); err = via_smart51_build(codec); if (err < 0) return err; return 1; } Loading Loading @@ -2884,7 +2907,10 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) if (spec->hp_mux) via_hp_build(codec); via_smart51_build(spec); err = via_smart51_build(codec); if (err < 0) return err; return 1; } Loading Loading @@ -3267,7 +3293,10 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) if (spec->hp_mux) via_hp_build(codec); via_smart51_build(spec); err = via_smart51_build(codec); if (err < 0) return err; return 1; } Loading Loading @@ -3775,7 +3804,9 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec) if (spec->hp_mux) via_hp_build(codec); via_smart51_build(spec); err = via_smart51_build(codec); if (err < 0) return err; return 1; } Loading Loading @@ -4127,7 +4158,9 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec) if (spec->hp_mux) via_hp_build(codec); via_smart51_build(spec); err = via_smart51_build(codec); if (err < 0) return err; return 1; } Loading Loading
sound/pci/hda/patch_via.c +75 −42 Original line number Diff line number Diff line Loading @@ -162,6 +162,7 @@ struct via_spec { const struct hda_input_mux *hp_mux; unsigned int hp_independent_mode; unsigned int hp_independent_mode_index; unsigned int can_smart51; unsigned int smart51_enabled; unsigned int dmic_enabled; unsigned int no_pin_power_ctl; Loading Loading @@ -544,7 +545,7 @@ static void via_auto_init_hp_out(struct hda_codec *codec) } } static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin); static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin); static void via_auto_init_analog_input(struct hda_codec *codec) { Loading @@ -555,7 +556,7 @@ static void via_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t nid = cfg->inputs[i].pin; if (spec->smart51_enabled && is_smart51_pins(spec, nid)) if (spec->smart51_enabled && is_smart51_pins(codec, nid)) ctl = PIN_OUT; else if (cfg->inputs[i].type == AUTO_PIN_MIC) ctl = PIN_VREF50; Loading @@ -580,7 +581,7 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, no_presence |= spec->no_pin_power_ctl; if (!no_presence) present = snd_hda_jack_detect(codec, nid); if ((spec->smart51_enabled && is_smart51_pins(spec, nid)) if ((spec->smart51_enabled && is_smart51_pins(codec, nid)) || ((no_presence || present) && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) { *affected_parm = AC_PWRST_D0; /* if it's connected */ Loading Loading @@ -919,16 +920,25 @@ static void mute_aa_path(struct hda_codec *codec, int mute) HDA_AMP_MUTE, val); } } static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin) static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin) { struct via_spec *spec = codec->spec; const struct auto_pin_cfg *cfg = &spec->autocfg; int i; for (i = 0; i < cfg->num_inputs; i++) { if (pin == cfg->inputs[i].pin) return cfg->inputs[i].type <= AUTO_PIN_LINE_IN; unsigned int defcfg; if (pin != cfg->inputs[i].pin) continue; if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) return false; defcfg = snd_hda_codec_get_pincfg(codec, pin); if (snd_hda_get_input_pin_attr(defcfg) < INPUT_PIN_ATTR_NORMAL) return false; return true; } return 0; return false; } static int via_smart51_info(struct snd_kcontrol *kcontrol, Loading @@ -952,13 +962,14 @@ static int via_smart51_get(struct snd_kcontrol *kcontrol, for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t nid = cfg->inputs[i].pin; int ctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) continue; unsigned int ctl; if (cfg->inputs[i].type == AUTO_PIN_MIC && spec->hp_independent_mode && spec->codec_type != VT1718S) continue; /* ignore FMic for independent HP */ if (!is_smart51_pins(codec, nid)) continue; ctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); if ((ctl & AC_PINCTL_IN_EN) && !(ctl & AC_PINCTL_OUT_EN)) on = 0; } Loading @@ -980,11 +991,11 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol, hda_nid_t nid = cfg->inputs[i].pin; unsigned int parm; if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) continue; if (cfg->inputs[i].type == AUTO_PIN_MIC && spec->hp_independent_mode && spec->codec_type != VT1718S) continue; /* don't retask FMic for independent HP */ if (!is_smart51_pins(codec, nid)) continue; parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); Loading @@ -997,23 +1008,6 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol, mute_aa_path(codec, 1); notify_aa_path_ctls(codec); } if (spec->codec_type == VT1718S) { snd_hda_codec_amp_stereo( codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_UNMUTE); } if (cfg->inputs[i].type == AUTO_PIN_MIC) { if (spec->codec_type == VT1708S || spec->codec_type == VT1716S) { /* input = index 1 (AOW3) */ snd_hda_codec_write( codec, nid, 0, AC_VERB_SET_CONNECT_SEL, 1); snd_hda_codec_amp_stereo( codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_UNMUTE); } } } spec->smart51_enabled = *ucontrol->value.integer.value; set_widgets_power_state(codec); Loading @@ -1029,16 +1023,15 @@ static const struct snd_kcontrol_new via_smart51_mixer = { .put = via_smart51_put, }; static int via_smart51_build(struct via_spec *spec) static int via_smart51_build(struct hda_codec *codec) { struct via_spec *spec = codec->spec; struct snd_kcontrol_new *knew; const struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t nid; int i; if (!cfg) return 0; if (cfg->line_outs > 2) if (!spec->can_smart51) return 0; knew = via_clone_control(spec, &via_smart51_mixer); Loading @@ -1047,7 +1040,7 @@ static int via_smart51_build(struct via_spec *spec) for (i = 0; i < cfg->num_inputs; i++) { nid = cfg->inputs[i].pin; if (cfg->inputs[i].type <= AUTO_PIN_LINE_IN) { if (is_smart51_pins(codec, nid)) { knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; break; } Loading Loading @@ -1943,15 +1936,37 @@ static int create_ch_ctls(struct hda_codec *codec, const char *pfx, static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, hda_nid_t nid); static void mangle_smart51(struct hda_codec *codec) { struct via_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; int i; for (i = 0; i < cfg->num_inputs; i++) { if (!is_smart51_pins(codec, cfg->inputs[i].pin)) continue; spec->can_smart51 = 1; cfg->line_out_pins[cfg->line_outs++] = cfg->inputs[i].pin; if (cfg->line_outs == 3) break; } } /* add playback controls from the parsed DAC table */ static int via_auto_create_multi_out_ctls(struct hda_codec *codec) { struct via_spec *spec = codec->spec; const struct auto_pin_cfg *cfg = &spec->autocfg; struct auto_pin_cfg *cfg = &spec->autocfg; static const char * const chname[4] = { "Front", "Surround", "C/LFE", "Side" }; int i, idx, err; int old_line_outs; /* check smart51 */ old_line_outs = cfg->line_outs; if (cfg->line_outs == 1) mangle_smart51(codec); for (i = 0; i < cfg->line_outs; i++) { hda_nid_t pin, dac; Loading Loading @@ -1991,6 +2006,8 @@ static int via_auto_create_multi_out_ctls(struct hda_codec *codec) return err; } cfg->line_outs = old_line_outs; return 0; } Loading Loading @@ -2246,7 +2263,10 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) if (spec->hp_mux) via_hp_build(codec); via_smart51_build(spec); err = via_smart51_build(codec); if (err < 0) return err; return 1; } Loading Loading @@ -2523,7 +2543,10 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) if (spec->hp_mux) via_hp_build(codec); via_smart51_build(spec); err = via_smart51_build(codec); if (err < 0) return err; return 1; } Loading Loading @@ -2884,7 +2907,10 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) if (spec->hp_mux) via_hp_build(codec); via_smart51_build(spec); err = via_smart51_build(codec); if (err < 0) return err; return 1; } Loading Loading @@ -3267,7 +3293,10 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) if (spec->hp_mux) via_hp_build(codec); via_smart51_build(spec); err = via_smart51_build(codec); if (err < 0) return err; return 1; } Loading Loading @@ -3775,7 +3804,9 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec) if (spec->hp_mux) via_hp_build(codec); via_smart51_build(spec); err = via_smart51_build(codec); if (err < 0) return err; return 1; } Loading Loading @@ -4127,7 +4158,9 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec) if (spec->hp_mux) via_hp_build(codec); via_smart51_build(spec); err = via_smart51_build(codec); if (err < 0) return err; return 1; } Loading