diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 49 |
1 files changed, 34 insertions, 15 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5c81ee95d7f..40dda2a8377 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -303,6 +303,38 @@ static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) | |||
303 | static void call_update_outputs(struct hda_codec *codec); | 303 | static void call_update_outputs(struct hda_codec *codec); |
304 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force); | 304 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force); |
305 | 305 | ||
306 | /* for shared I/O, change the pin-control accordingly */ | ||
307 | static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic) | ||
308 | { | ||
309 | struct alc_spec *spec = codec->spec; | ||
310 | unsigned int val; | ||
311 | hda_nid_t pin = spec->autocfg.inputs[1].pin; | ||
312 | /* NOTE: this assumes that there are only two inputs, the | ||
313 | * first is the real internal mic and the second is HP/mic jack. | ||
314 | */ | ||
315 | |||
316 | val = snd_hda_get_default_vref(codec, pin); | ||
317 | |||
318 | /* This pin does not have vref caps - let's enable vref on pin 0x18 | ||
319 | instead, as suggested by Realtek */ | ||
320 | if (val == AC_PINCTL_VREF_HIZ) { | ||
321 | const hda_nid_t vref_pin = 0x18; | ||
322 | /* Sanity check pin 0x18 */ | ||
323 | if (get_wcaps_type(get_wcaps(codec, vref_pin)) == AC_WID_PIN && | ||
324 | get_defcfg_connect(snd_hda_codec_get_pincfg(codec, vref_pin)) == AC_JACK_PORT_NONE) { | ||
325 | unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin); | ||
326 | if (vref_val != AC_PINCTL_VREF_HIZ) | ||
327 | snd_hda_set_pin_ctl(codec, vref_pin, PIN_IN | (set_as_mic ? vref_val : 0)); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | val = set_as_mic ? val | PIN_IN : PIN_HP; | ||
332 | snd_hda_set_pin_ctl(codec, pin, val); | ||
333 | |||
334 | spec->automute_speaker = !set_as_mic; | ||
335 | call_update_outputs(codec); | ||
336 | } | ||
337 | |||
306 | /* select the given imux item; either unmute exclusively or select the route */ | 338 | /* select the given imux item; either unmute exclusively or select the route */ |
307 | static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | 339 | static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, |
308 | unsigned int idx, bool force) | 340 | unsigned int idx, bool force) |
@@ -329,21 +361,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
329 | return 0; | 361 | return 0; |
330 | spec->cur_mux[adc_idx] = idx; | 362 | spec->cur_mux[adc_idx] = idx; |
331 | 363 | ||
332 | /* for shared I/O, change the pin-control accordingly */ | 364 | if (spec->shared_mic_hp) |
333 | if (spec->shared_mic_hp) { | 365 | update_shared_mic_hp(codec, spec->cur_mux[adc_idx]); |
334 | unsigned int val; | ||
335 | hda_nid_t pin = spec->autocfg.inputs[1].pin; | ||
336 | /* NOTE: this assumes that there are only two inputs, the | ||
337 | * first is the real internal mic and the second is HP jack. | ||
338 | */ | ||
339 | if (spec->cur_mux[adc_idx]) | ||
340 | val = snd_hda_get_default_vref(codec, pin) | PIN_IN; | ||
341 | else | ||
342 | val = PIN_HP; | ||
343 | snd_hda_set_pin_ctl(codec, pin, val); | ||
344 | spec->automute_speaker = !spec->cur_mux[adc_idx]; | ||
345 | call_update_outputs(codec); | ||
346 | } | ||
347 | 366 | ||
348 | if (spec->dyn_adc_switch) { | 367 | if (spec->dyn_adc_switch) { |
349 | alc_dyn_adc_pcm_resetup(codec, idx); | 368 | alc_dyn_adc_pcm_resetup(codec, idx); |