aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-04-20 07:06:53 -0400
committerTakashi Iwai <tiwai@suse.de>2012-04-20 07:06:53 -0400
commit4740860b534e86d7db3b26cbd980bec8e4c807e8 (patch)
treedf010ab3c53a2b4f3829593b56cdfa19f829115b /sound
parentcdd03cedc5b55da017fcdeff7d47cac2639cded8 (diff)
ALSA: hda - Add snd_hda_get_default_vref() helper function
Add a new helper function to guess the default VREF pin control bits for mic in. This can be used to set the pin control value safely matching with the actual pin capabilities. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_codec.c27
-rw-r--r--sound/pci/hda/hda_local.h2
-rw-r--r--sound/pci/hda/patch_analog.c7
-rw-r--r--sound/pci/hda/patch_ca0110.c3
-rw-r--r--sound/pci/hda/patch_ca0132.c3
-rw-r--r--sound/pci/hda/patch_cirrus.c8
-rw-r--r--sound/pci/hda/patch_conexant.c9
-rw-r--r--sound/pci/hda/patch_realtek.c22
-rw-r--r--sound/pci/hda/patch_sigmatel.c26
-rw-r--r--sound/pci/hda/patch_via.c7
10 files changed, 56 insertions, 58 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 2d9716e7a116..8b8b74a1284c 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -4795,6 +4795,33 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
4795} 4795}
4796EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup); 4796EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup);
4797 4797
4798/**
4799 * snd_hda_get_default_vref - Get the default (mic) VREF pin bits
4800 *
4801 * Guess the suitable VREF pin bits to be set as the pin-control value.
4802 * Note: the function doesn't set the AC_PINCTL_IN_EN bit.
4803 */
4804unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin)
4805{
4806 unsigned int pincap;
4807 unsigned int oldval;
4808 oldval = snd_hda_codec_read(codec, pin, 0,
4809 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4810 pincap = snd_hda_query_pin_caps(codec, pin);
4811 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
4812 /* Exception: if the default pin setup is vref50, we give it priority */
4813 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
4814 return AC_PINCTL_VREF_80;
4815 else if (pincap & AC_PINCAP_VREF_50)
4816 return AC_PINCTL_VREF_50;
4817 else if (pincap & AC_PINCAP_VREF_100)
4818 return AC_PINCTL_VREF_100;
4819 else if (pincap & AC_PINCAP_VREF_GRD)
4820 return AC_PINCTL_VREF_GRD;
4821 return AC_PINCTL_VREF_HIZ;
4822}
4823EXPORT_SYMBOL_HDA(snd_hda_get_default_vref);
4824
4798int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, 4825int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
4799 unsigned int val, bool cached) 4826 unsigned int val, bool cached)
4800{ 4827{
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 17d425775c99..a5cee952547d 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -502,6 +502,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
502#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN) 502#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN)
503#define PIN_HP_AMP (AC_PINCTL_HP_EN) 503#define PIN_HP_AMP (AC_PINCTL_HP_EN)
504 504
505unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin);
505int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, 506int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
506 unsigned int val, bool cached); 507 unsigned int val, bool cached);
507 508
@@ -517,6 +518,7 @@ int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
517 * HP-drive capability, the HP bit is omitted. 518 * HP-drive capability, the HP bit is omitted.
518 * 519 *
519 * The function doesn't check the input VREF capability bits, though. 520 * The function doesn't check the input VREF capability bits, though.
521 * Use snd_hda_get_default_vref() to guess the right value.
520 * Also, this function is only for analog pins, not for HDMI pins. 522 * Also, this function is only for analog pins, not for HDMI pins.
521 */ 523 */
522static inline int 524static inline int
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 38163abeea92..723bb9cb5f09 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -3155,6 +3155,7 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec)
3155 for (i = 0; i < cfg->num_inputs; i++) { 3155 for (i = 0; i < cfg->num_inputs; i++) {
3156 hda_nid_t nid = cfg->inputs[i].pin; 3156 hda_nid_t nid = cfg->inputs[i].pin;
3157 int type = cfg->inputs[i].type; 3157 int type = cfg->inputs[i].type;
3158 int val;
3158 switch (nid) { 3159 switch (nid) {
3159 case 0x15: /* port-C */ 3160 case 0x15: /* port-C */
3160 snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0); 3161 snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
@@ -3163,8 +3164,10 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec)
3163 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0); 3164 snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
3164 break; 3165 break;
3165 } 3166 }
3166 snd_hda_set_pin_ctl(codec, nid, 3167 val = PIN_IN;
3167 type == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN); 3168 if (type == AUTO_PIN_MIC)
3169 val |= snd_hda_get_default_vref(codec, nid);
3170 snd_hda_set_pin_ctl(codec, nid, val);
3168 if (nid != AD1988_PIN_CD_NID) 3171 if (nid != AD1988_PIN_CD_NID)
3169 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 3172 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3170 AMP_OUT_MUTE); 3173 AMP_OUT_MUTE);
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
index 646dc976f4bd..a3b70a8f6df8 100644
--- a/sound/pci/hda/patch_ca0110.c
+++ b/sound/pci/hda/patch_ca0110.c
@@ -355,7 +355,8 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
355static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) 355static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
356{ 356{
357 if (pin) { 357 if (pin) {
358 snd_hda_set_pin_ctl(codec, pin, PIN_VREF80); 358 snd_hda_set_pin_ctl(codec, pin, PIN_IN |
359 snd_hda_get_default_vref(codec, pin));
359 if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP) 360 if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
360 snd_hda_codec_write(codec, pin, 0, 361 snd_hda_codec_write(codec, pin, 0,
361 AC_VERB_SET_AMP_GAIN_MUTE, 362 AC_VERB_SET_AMP_GAIN_MUTE,
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index ea63333f41fe..d290a8ff0108 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -253,7 +253,8 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
253static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) 253static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
254{ 254{
255 if (pin) { 255 if (pin) {
256 snd_hda_set_pin_ctl(codec, pin, PIN_VREF80); 256 snd_hda_set_pin_ctl(codec, pin, PIN_IN |
257 snd_hda_get_default_vref(codec, pin));
257 if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP) 258 if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
258 snd_hda_codec_write(codec, pin, 0, 259 snd_hda_codec_write(codec, pin, 0,
259 AC_VERB_SET_AMP_GAIN_MUTE, 260 AC_VERB_SET_AMP_GAIN_MUTE,
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 778e4b9dd88c..48c6d8186e90 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -1057,12 +1057,8 @@ static void init_input(struct hda_codec *codec)
1057 continue; 1057 continue;
1058 /* set appropriate pin control and mute first */ 1058 /* set appropriate pin control and mute first */
1059 ctl = PIN_IN; 1059 ctl = PIN_IN;
1060 if (cfg->inputs[i].type == AUTO_PIN_MIC) { 1060 if (cfg->inputs[i].type == AUTO_PIN_MIC)
1061 unsigned int caps = snd_hda_query_pin_caps(codec, pin); 1061 ctl |= snd_hda_get_default_vref(codec, pin);
1062 caps >>= AC_PINCAP_VREF_SHIFT;
1063 if (caps & AC_PINCAP_VREF_80)
1064 ctl = PIN_VREF80;
1065 }
1066 snd_hda_set_pin_ctl(codec, pin, ctl); 1062 snd_hda_set_pin_ctl(codec, pin, ctl);
1067 snd_hda_codec_write(codec, spec->adc_nid[i], 0, 1063 snd_hda_codec_write(codec, spec->adc_nid[i], 0,
1068 AC_VERB_SET_AMP_GAIN_MUTE, 1064 AC_VERB_SET_AMP_GAIN_MUTE,
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index afa510f0b993..aabdb9e9a484 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -4020,12 +4020,11 @@ static void cx_auto_init_input(struct hda_codec *codec)
4020 } 4020 }
4021 4021
4022 for (i = 0; i < cfg->num_inputs; i++) { 4022 for (i = 0; i < cfg->num_inputs; i++) {
4023 unsigned int type; 4023 hda_nid_t pin = cfg->inputs[i].pin;
4024 unsigned int type = PIN_IN;
4024 if (cfg->inputs[i].type == AUTO_PIN_MIC) 4025 if (cfg->inputs[i].type == AUTO_PIN_MIC)
4025 type = PIN_VREF80; 4026 type |= snd_hda_get_default_vref(codec, pin);
4026 else 4027 snd_hda_set_pin_ctl(codec, pin, type);
4027 type = PIN_IN;
4028 snd_hda_set_pin_ctl(codec, cfg->inputs[i].pin, type);
4029 } 4028 }
4030 4029
4031 if (spec->auto_mic) { 4030 if (spec->auto_mic) {
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 9560b8e1e85c..951a090cef4a 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -325,7 +325,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
325 * first is the real internal mic and the second is HP jack. 325 * first is the real internal mic and the second is HP jack.
326 */ 326 */
327 if (spec->cur_mux[adc_idx]) 327 if (spec->cur_mux[adc_idx])
328 val = PIN_VREF80; 328 val = snd_hda_get_default_vref(codec, pin) | PIN_IN;
329 else 329 else
330 val = PIN_HP; 330 val = PIN_HP;
331 snd_hda_set_pin_ctl(codec, pin, val); 331 snd_hda_set_pin_ctl(codec, pin, val);
@@ -379,24 +379,8 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
379 int auto_pin_type) 379 int auto_pin_type)
380{ 380{
381 unsigned int val = PIN_IN; 381 unsigned int val = PIN_IN;
382 382 if (auto_pin_type == AUTO_PIN_MIC)
383 if (auto_pin_type == AUTO_PIN_MIC) { 383 val |= snd_hda_get_default_vref(codec, nid);
384 unsigned int pincap;
385 unsigned int oldval;
386 oldval = snd_hda_codec_read(codec, nid, 0,
387 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
388 pincap = snd_hda_query_pin_caps(codec, nid);
389 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
390 /* if the default pin setup is vref50, we give it priority */
391 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
392 val = PIN_VREF80;
393 else if (pincap & AC_PINCAP_VREF_50)
394 val = PIN_VREF50;
395 else if (pincap & AC_PINCAP_VREF_100)
396 val = PIN_VREF100;
397 else if (pincap & AC_PINCAP_VREF_GRD)
398 val = PIN_VREFGRD;
399 }
400 snd_hda_set_pin_ctl(codec, nid, val); 384 snd_hda_set_pin_ctl(codec, nid, val);
401} 385}
402 386
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 21de62b7c991..884f8ad351fd 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -2503,22 +2503,6 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
2503 return 0; 2503 return 0;
2504} 2504}
2505 2505
2506static unsigned int stac92xx_get_default_vref(struct hda_codec *codec,
2507 hda_nid_t nid)
2508{
2509 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
2510 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
2511 if (pincap & AC_PINCAP_VREF_100)
2512 return AC_PINCTL_VREF_100;
2513 if (pincap & AC_PINCAP_VREF_80)
2514 return AC_PINCTL_VREF_80;
2515 if (pincap & AC_PINCAP_VREF_50)
2516 return AC_PINCTL_VREF_50;
2517 if (pincap & AC_PINCAP_VREF_GRD)
2518 return AC_PINCTL_VREF_GRD;
2519 return 0;
2520}
2521
2522static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type) 2506static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int pin_type)
2523 2507
2524{ 2508{
@@ -2591,7 +2575,7 @@ static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol,
2591 hda_nid_t nid = kcontrol->private_value; 2575 hda_nid_t nid = kcontrol->private_value;
2592 unsigned int vref = stac92xx_vref_get(codec, nid); 2576 unsigned int vref = stac92xx_vref_get(codec, nid);
2593 2577
2594 if (vref == stac92xx_get_default_vref(codec, nid)) 2578 if (vref == snd_hda_get_default_vref(codec, nid))
2595 ucontrol->value.enumerated.item[0] = 0; 2579 ucontrol->value.enumerated.item[0] = 0;
2596 else if (vref == AC_PINCTL_VREF_GRD) 2580 else if (vref == AC_PINCTL_VREF_GRD)
2597 ucontrol->value.enumerated.item[0] = 1; 2581 ucontrol->value.enumerated.item[0] = 1;
@@ -2610,7 +2594,7 @@ static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
2610 hda_nid_t nid = kcontrol->private_value; 2594 hda_nid_t nid = kcontrol->private_value;
2611 2595
2612 if (ucontrol->value.enumerated.item[0] == 0) 2596 if (ucontrol->value.enumerated.item[0] == 0)
2613 new_vref = stac92xx_get_default_vref(codec, nid); 2597 new_vref = snd_hda_get_default_vref(codec, nid);
2614 else if (ucontrol->value.enumerated.item[0] == 1) 2598 else if (ucontrol->value.enumerated.item[0] == 1)
2615 new_vref = AC_PINCTL_VREF_GRD; 2599 new_vref = AC_PINCTL_VREF_GRD;
2616 else if (ucontrol->value.enumerated.item[0] == 2) 2600 else if (ucontrol->value.enumerated.item[0] == 2)
@@ -2676,7 +2660,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
2676 else { 2660 else {
2677 unsigned int pinctl = AC_PINCTL_IN_EN; 2661 unsigned int pinctl = AC_PINCTL_IN_EN;
2678 if (io_idx) /* set VREF for mic */ 2662 if (io_idx) /* set VREF for mic */
2679 pinctl |= stac92xx_get_default_vref(codec, nid); 2663 pinctl |= snd_hda_get_default_vref(codec, nid);
2680 stac92xx_auto_set_pinctl(codec, nid, pinctl); 2664 stac92xx_auto_set_pinctl(codec, nid, pinctl);
2681 } 2665 }
2682 2666
@@ -2844,7 +2828,7 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
2844 char name[22]; 2828 char name[22];
2845 2829
2846 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) { 2830 if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
2847 if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD 2831 if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
2848 && nid == spec->line_switch) 2832 && nid == spec->line_switch)
2849 control = STAC_CTL_WIDGET_IO_SWITCH; 2833 control = STAC_CTL_WIDGET_IO_SWITCH;
2850 else if (snd_hda_query_pin_caps(codec, nid) 2834 else if (snd_hda_query_pin_caps(codec, nid)
@@ -4351,7 +4335,7 @@ static int stac92xx_init(struct hda_codec *codec)
4351 unsigned int pinctl, conf; 4335 unsigned int pinctl, conf;
4352 if (type == AUTO_PIN_MIC) { 4336 if (type == AUTO_PIN_MIC) {
4353 /* for mic pins, force to initialize */ 4337 /* for mic pins, force to initialize */
4354 pinctl = stac92xx_get_default_vref(codec, nid); 4338 pinctl = snd_hda_get_default_vref(codec, nid);
4355 pinctl |= AC_PINCTL_IN_EN; 4339 pinctl |= AC_PINCTL_IN_EN;
4356 stac92xx_auto_set_pinctl(codec, nid, pinctl); 4340 stac92xx_auto_set_pinctl(codec, nid, pinctl);
4357 } else { 4341 } else {
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 8ee531aeda6e..92e11672b91c 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -661,10 +661,11 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
661 hda_nid_t nid = cfg->inputs[i].pin; 661 hda_nid_t nid = cfg->inputs[i].pin;
662 if (spec->smart51_enabled && is_smart51_pins(codec, nid)) 662 if (spec->smart51_enabled && is_smart51_pins(codec, nid))
663 ctl = PIN_OUT; 663 ctl = PIN_OUT;
664 else if (cfg->inputs[i].type == AUTO_PIN_MIC) 664 else {
665 ctl = PIN_VREF50;
666 else
667 ctl = PIN_IN; 665 ctl = PIN_IN;
666 if (cfg->inputs[i].type == AUTO_PIN_MIC)
667 ctl |= snd_hda_get_default_vref(codec, nid);
668 }
668 snd_hda_set_pin_ctl(codec, nid, ctl); 669 snd_hda_set_pin_ctl(codec, nid, ctl);
669 } 670 }
670 671