ALSA: hda - Introduce snd_hda_set_pin_ctl*() helper functions
For setting the pin-control values more safely to match with the actual pin capability bits, a copule of new helper functions, snd_hda_set_pin_ctl() and snd_hda_set_pin_ctl_cache(), are introduced. These are simple replacement of the codec verb write with AC_VERB_SET_PIN_WIDGET but do more sanity checks and filter out superfluous pin-control bits if they don't fit with the corresponding pin capabilities. Some codecs are screwed up or ignore the command when such a wrong bit is set. These helpers will avoid such secret errors. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
@@ -933,8 +933,7 @@ static void cs_automute(struct hda_codec *codec)
|
||||
pin_ctl = 0;
|
||||
|
||||
nid = cfg->speaker_pins[i];
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl);
|
||||
snd_hda_set_pin_ctl(codec, nid, pin_ctl);
|
||||
}
|
||||
if (spec->gpio_eapd_hp) {
|
||||
unsigned int gpio = hp_present ?
|
||||
@@ -948,16 +947,14 @@ static void cs_automute(struct hda_codec *codec)
|
||||
/* mute HPs if spdif jack (SENSE_B) is present */
|
||||
for (i = 0; i < cfg->hp_outs; i++) {
|
||||
nid = cfg->hp_pins[i];
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
snd_hda_set_pin_ctl(codec, nid,
|
||||
(spdif_present && spec->sense_b) ? 0 : PIN_HP);
|
||||
}
|
||||
|
||||
/* SPDIF TX on/off */
|
||||
if (cfg->dig_outs) {
|
||||
nid = cfg->dig_out_pins[0];
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL,
|
||||
snd_hda_set_pin_ctl(codec, nid,
|
||||
spdif_present ? PIN_OUT : 0);
|
||||
|
||||
}
|
||||
@@ -1024,13 +1021,11 @@ static void init_output(struct hda_codec *codec)
|
||||
|
||||
/* set appropriate pin controls */
|
||||
for (i = 0; i < cfg->line_outs; i++)
|
||||
snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||
snd_hda_set_pin_ctl(codec, cfg->line_out_pins[i], PIN_OUT);
|
||||
/* HP */
|
||||
for (i = 0; i < cfg->hp_outs; i++) {
|
||||
hda_nid_t nid = cfg->hp_pins[i];
|
||||
snd_hda_codec_write(codec, nid, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
|
||||
snd_hda_set_pin_ctl(codec, nid, PIN_HP);
|
||||
if (!cfg->speaker_outs)
|
||||
continue;
|
||||
if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
|
||||
@@ -1041,8 +1036,7 @@ static void init_output(struct hda_codec *codec)
|
||||
|
||||
/* Speaker */
|
||||
for (i = 0; i < cfg->speaker_outs; i++)
|
||||
snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
||||
snd_hda_set_pin_ctl(codec, cfg->speaker_pins[i], PIN_OUT);
|
||||
|
||||
/* SPDIF is enabled on presence detect for CS421x */
|
||||
if (spec->hp_detect || spec->spdif_detect)
|
||||
@@ -1069,8 +1063,7 @@ static void init_input(struct hda_codec *codec)
|
||||
if (caps & AC_PINCAP_VREF_80)
|
||||
ctl = PIN_VREF80;
|
||||
}
|
||||
snd_hda_codec_write(codec, pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
|
||||
snd_hda_set_pin_ctl(codec, pin, ctl);
|
||||
snd_hda_codec_write(codec, spec->adc_nid[i], 0,
|
||||
AC_VERB_SET_AMP_GAIN_MUTE,
|
||||
AMP_IN_MUTE(spec->adc_idx[i]));
|
||||
|
Reference in New Issue
Block a user