aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_conexant.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-04-20 06:34:50 -0400
committerTakashi Iwai <tiwai@suse.de>2012-04-20 06:38:48 -0400
commitcdd03cedc5b55da017fcdeff7d47cac2639cded8 (patch)
treeb0b8b8360eb22f79b81ded6ef9981639be15010d /sound/pci/hda/patch_conexant.c
parentd39801105722c9aef9eae180656190c399c576a9 (diff)
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>
Diffstat (limited to 'sound/pci/hda/patch_conexant.c')
-rw-r--r--sound/pci/hda/patch_conexant.c44
1 files changed, 15 insertions, 29 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 6e04c2bf06de..afa510f0b993 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -1602,17 +1602,13 @@ static void cxt5051_update_speaker(struct hda_codec *codec)
1602 unsigned int pinctl; 1602 unsigned int pinctl;
1603 /* headphone pin */ 1603 /* headphone pin */
1604 pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0; 1604 pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
1605 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1605 snd_hda_set_pin_ctl(codec, 0x16, pinctl);
1606 pinctl);
1607 /* speaker pin */ 1606 /* speaker pin */
1608 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 1607 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1609 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1608 snd_hda_set_pin_ctl(codec, 0x1a, pinctl);
1610 pinctl);
1611 /* on ideapad there is an additional speaker (subwoofer) to mute */ 1609 /* on ideapad there is an additional speaker (subwoofer) to mute */
1612 if (spec->ideapad) 1610 if (spec->ideapad)
1613 snd_hda_codec_write(codec, 0x1b, 0, 1611 snd_hda_set_pin_ctl(codec, 0x1b, pinctl);
1614 AC_VERB_SET_PIN_WIDGET_CONTROL,
1615 pinctl);
1616} 1612}
1617 1613
1618/* turn on/off EAPD (+ mute HP) as a master switch */ 1614/* turn on/off EAPD (+ mute HP) as a master switch */
@@ -1997,8 +1993,7 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
1997 1993
1998 /* Port A (HP) */ 1994 /* Port A (HP) */
1999 pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0; 1995 pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
2000 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1996 snd_hda_set_pin_ctl(codec, 0x19, pinctl);
2001 pinctl);
2002 1997
2003 /* Port D (HP/LO) */ 1998 /* Port D (HP/LO) */
2004 pinctl = spec->cur_eapd ? spec->port_d_mode : 0; 1999 pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
@@ -2011,13 +2006,11 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
2011 if (!hp_port_d_present(spec)) 2006 if (!hp_port_d_present(spec))
2012 pinctl = 0; 2007 pinctl = 0;
2013 } 2008 }
2014 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2009 snd_hda_set_pin_ctl(codec, 0x1c, pinctl);
2015 pinctl);
2016 2010
2017 /* CLASS_D AMP */ 2011 /* CLASS_D AMP */
2018 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 2012 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
2019 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2013 snd_hda_set_pin_ctl(codec, 0x1f, pinctl);
2020 pinctl);
2021} 2014}
2022 2015
2023/* turn on/off EAPD (+ mute HP) as a master switch */ 2016/* turn on/off EAPD (+ mute HP) as a master switch */
@@ -2048,8 +2041,7 @@ static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
2048 /* Even though port F is the DC input, the bias is controlled on port B. 2041 /* Even though port F is the DC input, the bias is controlled on port B.
2049 * we also leave that port as an active input (but unselected) in DC mode 2042 * we also leave that port as an active input (but unselected) in DC mode
2050 * just in case that is necessary to make the bias setting take effect. */ 2043 * just in case that is necessary to make the bias setting take effect. */
2051 return snd_hda_codec_write_cache(codec, 0x1a, 0, 2044 return snd_hda_set_pin_ctl_cache(codec, 0x1a,
2052 AC_VERB_SET_PIN_WIDGET_CONTROL,
2053 cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index); 2045 cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
2054} 2046}
2055 2047
@@ -2082,14 +2074,14 @@ static void cxt5066_olpc_select_mic(struct hda_codec *codec)
2082 } 2074 }
2083 2075
2084 /* disable DC (port F) */ 2076 /* disable DC (port F) */
2085 snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0); 2077 snd_hda_set_pin_ctl(codec, 0x1e, 0);
2086 2078
2087 /* external mic, port B */ 2079 /* external mic, port B */
2088 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2080 snd_hda_set_pin_ctl(codec, 0x1a,
2089 spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0); 2081 spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
2090 2082
2091 /* internal mic, port C */ 2083 /* internal mic, port C */
2092 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2084 snd_hda_set_pin_ctl(codec, 0x1b,
2093 spec->ext_mic_present ? 0 : PIN_VREF80); 2085 spec->ext_mic_present ? 0 : PIN_VREF80);
2094} 2086}
2095 2087
@@ -3358,9 +3350,7 @@ static void do_automute(struct hda_codec *codec, int num_pins,
3358 struct conexant_spec *spec = codec->spec; 3350 struct conexant_spec *spec = codec->spec;
3359 int i; 3351 int i;
3360 for (i = 0; i < num_pins; i++) 3352 for (i = 0; i < num_pins; i++)
3361 snd_hda_codec_write(codec, pins[i], 0, 3353 snd_hda_set_pin_ctl(codec, pins[i], on ? PIN_OUT : 0);
3362 AC_VERB_SET_PIN_WIDGET_CONTROL,
3363 on ? PIN_OUT : 0);
3364 if (spec->pin_eapd_ctrls) 3354 if (spec->pin_eapd_ctrls)
3365 cx_auto_turn_eapd(codec, num_pins, pins, on); 3355 cx_auto_turn_eapd(codec, num_pins, pins, on);
3366} 3356}
@@ -3977,8 +3967,7 @@ static void cx_auto_init_output(struct hda_codec *codec)
3977 if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) & 3967 if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) &
3978 AC_PINCAP_HP_DRV) 3968 AC_PINCAP_HP_DRV)
3979 val |= AC_PINCTL_HP_EN; 3969 val |= AC_PINCTL_HP_EN;
3980 snd_hda_codec_write(codec, cfg->hp_pins[i], 0, 3970 snd_hda_set_pin_ctl(codec, cfg->hp_pins[i], val);
3981 AC_VERB_SET_PIN_WIDGET_CONTROL, val);
3982 } 3971 }
3983 mute_outputs(codec, cfg->hp_outs, cfg->hp_pins); 3972 mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
3984 mute_outputs(codec, cfg->line_outs, cfg->line_out_pins); 3973 mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
@@ -4036,8 +4025,7 @@ static void cx_auto_init_input(struct hda_codec *codec)
4036 type = PIN_VREF80; 4025 type = PIN_VREF80;
4037 else 4026 else
4038 type = PIN_IN; 4027 type = PIN_IN;
4039 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0, 4028 snd_hda_set_pin_ctl(codec, cfg->inputs[i].pin, type);
4040 AC_VERB_SET_PIN_WIDGET_CONTROL, type);
4041 } 4029 }
4042 4030
4043 if (spec->auto_mic) { 4031 if (spec->auto_mic) {
@@ -4064,11 +4052,9 @@ static void cx_auto_init_digital(struct hda_codec *codec)
4064 struct auto_pin_cfg *cfg = &spec->autocfg; 4052 struct auto_pin_cfg *cfg = &spec->autocfg;
4065 4053
4066 if (spec->multiout.dig_out_nid) 4054 if (spec->multiout.dig_out_nid)
4067 snd_hda_codec_write(codec, cfg->dig_out_pins[0], 0, 4055 snd_hda_set_pin_ctl(codec, cfg->dig_out_pins[0], PIN_OUT);
4068 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4069 if (spec->dig_in_nid) 4056 if (spec->dig_in_nid)
4070 snd_hda_codec_write(codec, cfg->dig_in_pin, 0, 4057 snd_hda_set_pin_ctl(codec, cfg->dig_in_pin, PIN_IN);
4071 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
4072} 4058}
4073 4059
4074static int cx_auto_init(struct hda_codec *codec) 4060static int cx_auto_init(struct hda_codec *codec)