From cdd03cedc5b55da017fcdeff7d47cac2639cded8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 20 Apr 2012 12:34:50 +0200 Subject: 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 --- sound/pci/hda/patch_cirrus.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'sound/pci/hda/patch_cirrus.c') diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index c83ccdba1e5..778e4b9dd88 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -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])); -- cgit v1.2.3