diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-12-19 03:26:08 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-12-19 09:09:36 -0500 |
commit | c21ca4a872697aeda4fe91bf9b6cc8380c62827c (patch) | |
tree | 9a30951ee842bb76cb6c3e8f00ee341fd9e2dc50 /sound | |
parent | 03c6901ea22bbb532586334d5b79941ccf56d5b0 (diff) |
ALSA: hda - Rework on STAC/IDT auto-configuration code
The current auto-configuration code has several problems especially
for the new IDT codecs, e.g. wrong assignment of pins and DACs or
coupled volume for speaker and headphone.
This patch is a fairly large rewrite of the auto-configuration code.
Some remaks
- mic_switch and line_switch contain NIDs instead of bool
- dac_list isn't fixed for IDT 92HD* codecs now, they are all probed
- extra HP and speakers are stored in extra_dacs[].
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 467 |
1 files changed, 204 insertions, 263 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index b7b419691803..171400216326 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -157,8 +157,6 @@ struct sigmatel_spec { | |||
157 | int board_config; | 157 | int board_config; |
158 | unsigned int eapd_switch: 1; | 158 | unsigned int eapd_switch: 1; |
159 | unsigned int surr_switch: 1; | 159 | unsigned int surr_switch: 1; |
160 | unsigned int line_switch: 1; | ||
161 | unsigned int mic_switch: 1; | ||
162 | unsigned int alt_switch: 1; | 160 | unsigned int alt_switch: 1; |
163 | unsigned int hp_detect: 1; | 161 | unsigned int hp_detect: 1; |
164 | unsigned int spdif_mute: 1; | 162 | unsigned int spdif_mute: 1; |
@@ -195,6 +193,8 @@ struct sigmatel_spec { | |||
195 | unsigned int cur_mmux; | 193 | unsigned int cur_mmux; |
196 | struct hda_multi_out multiout; | 194 | struct hda_multi_out multiout; |
197 | hda_nid_t dac_nids[5]; | 195 | hda_nid_t dac_nids[5]; |
196 | hda_nid_t hp_dacs[5]; | ||
197 | hda_nid_t speaker_dacs[5]; | ||
198 | 198 | ||
199 | /* capture */ | 199 | /* capture */ |
200 | hda_nid_t *adc_nids; | 200 | hda_nid_t *adc_nids; |
@@ -238,7 +238,9 @@ struct sigmatel_spec { | |||
238 | /* i/o switches */ | 238 | /* i/o switches */ |
239 | unsigned int io_switch[2]; | 239 | unsigned int io_switch[2]; |
240 | unsigned int clfe_swap; | 240 | unsigned int clfe_swap; |
241 | unsigned int hp_switch; /* NID of HP as line-out */ | 241 | hda_nid_t line_switch; /* shared line-in for input and output */ |
242 | hda_nid_t mic_switch; /* shared mic-in for input and output */ | ||
243 | hda_nid_t hp_switch; /* NID of HP as line-out */ | ||
242 | unsigned int aloopback; | 244 | unsigned int aloopback; |
243 | 245 | ||
244 | struct hda_pcm pcm_rec[2]; /* PCM information */ | 246 | struct hda_pcm pcm_rec[2]; /* PCM information */ |
@@ -289,9 +291,6 @@ static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { | |||
289 | }; | 291 | }; |
290 | 292 | ||
291 | #define STAC92HD73_DAC_COUNT 5 | 293 | #define STAC92HD73_DAC_COUNT 5 |
292 | static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = { | ||
293 | 0x15, 0x16, 0x17, 0x18, 0x19, | ||
294 | }; | ||
295 | 294 | ||
296 | static hda_nid_t stac92hd73xx_mux_nids[4] = { | 295 | static hda_nid_t stac92hd73xx_mux_nids[4] = { |
297 | 0x28, 0x29, 0x2a, 0x2b, | 296 | 0x28, 0x29, 0x2a, 0x2b, |
@@ -310,11 +309,7 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { | |||
310 | 0x11, 0x12, 0 | 309 | 0x11, 0x12, 0 |
311 | }; | 310 | }; |
312 | 311 | ||
313 | #define STAC92HD81_DAC_COUNT 2 | ||
314 | #define STAC92HD83_DAC_COUNT 3 | 312 | #define STAC92HD83_DAC_COUNT 3 |
315 | static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = { | ||
316 | 0x13, 0x14, 0x22, | ||
317 | }; | ||
318 | 313 | ||
319 | static hda_nid_t stac92hd83xxx_dmux_nids[2] = { | 314 | static hda_nid_t stac92hd83xxx_dmux_nids[2] = { |
320 | 0x17, 0x18, | 315 | 0x17, 0x18, |
@@ -356,10 +351,6 @@ static hda_nid_t stac92hd71bxx_smux_nids[2] = { | |||
356 | 0x24, 0x25, | 351 | 0x24, 0x25, |
357 | }; | 352 | }; |
358 | 353 | ||
359 | static hda_nid_t stac92hd71bxx_dac_nids[1] = { | ||
360 | 0x10, /*0x11, */ | ||
361 | }; | ||
362 | |||
363 | #define STAC92HD71BXX_NUM_DMICS 2 | 354 | #define STAC92HD71BXX_NUM_DMICS 2 |
364 | static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { | 355 | static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { |
365 | 0x18, 0x19, 0 | 356 | 0x18, 0x19, 0 |
@@ -761,10 +752,6 @@ static struct hda_verb stac9200_eapd_init[] = { | |||
761 | static struct hda_verb stac92hd73xx_6ch_core_init[] = { | 752 | static struct hda_verb stac92hd73xx_6ch_core_init[] = { |
762 | /* set master volume and direct control */ | 753 | /* set master volume and direct control */ |
763 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 754 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
764 | /* setup audio connections */ | ||
765 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
766 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
767 | { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
768 | /* setup adcs to point to mixer */ | 755 | /* setup adcs to point to mixer */ |
769 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, | 756 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, |
770 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, | 757 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, |
@@ -783,10 +770,6 @@ static struct hda_verb dell_eq_core_init[] = { | |||
783 | /* set master volume to max value without distortion | 770 | /* set master volume to max value without distortion |
784 | * and direct control */ | 771 | * and direct control */ |
785 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, | 772 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, |
786 | /* setup audio connections */ | ||
787 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
788 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
789 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
790 | /* setup adcs to point to mixer */ | 773 | /* setup adcs to point to mixer */ |
791 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, | 774 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, |
792 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, | 775 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, |
@@ -800,10 +783,6 @@ static struct hda_verb dell_eq_core_init[] = { | |||
800 | 783 | ||
801 | static struct hda_verb dell_m6_core_init[] = { | 784 | static struct hda_verb dell_m6_core_init[] = { |
802 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 785 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
803 | /* setup audio connections */ | ||
804 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
805 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
806 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
807 | /* setup adcs to point to mixer */ | 786 | /* setup adcs to point to mixer */ |
808 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, | 787 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, |
809 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, | 788 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, |
@@ -818,13 +797,6 @@ static struct hda_verb dell_m6_core_init[] = { | |||
818 | static struct hda_verb stac92hd73xx_8ch_core_init[] = { | 797 | static struct hda_verb stac92hd73xx_8ch_core_init[] = { |
819 | /* set master volume and direct control */ | 798 | /* set master volume and direct control */ |
820 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 799 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
821 | /* setup audio connections */ | ||
822 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
823 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
824 | { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
825 | /* connect hp ports to dac3 */ | ||
826 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
827 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
828 | /* setup adcs to point to mixer */ | 800 | /* setup adcs to point to mixer */ |
829 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, | 801 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, |
830 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, | 802 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, |
@@ -842,15 +814,8 @@ static struct hda_verb stac92hd73xx_8ch_core_init[] = { | |||
842 | static struct hda_verb stac92hd73xx_10ch_core_init[] = { | 814 | static struct hda_verb stac92hd73xx_10ch_core_init[] = { |
843 | /* set master volume and direct control */ | 815 | /* set master volume and direct control */ |
844 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 816 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
845 | /* setup audio connections */ | ||
846 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
847 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
848 | { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
849 | /* dac3 is connected to import3 mux */ | 817 | /* dac3 is connected to import3 mux */ |
850 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f}, | 818 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f}, |
851 | /* connect hp ports to dac4 */ | ||
852 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04}, | ||
853 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04}, | ||
854 | /* setup adcs to point to mixer */ | 819 | /* setup adcs to point to mixer */ |
855 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, | 820 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, |
856 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, | 821 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, |
@@ -881,8 +846,6 @@ static struct hda_verb stac92hd83xxx_core_init[] = { | |||
881 | static struct hda_verb stac92hd71bxx_core_init[] = { | 846 | static struct hda_verb stac92hd71bxx_core_init[] = { |
882 | /* set master volume and direct control */ | 847 | /* set master volume and direct control */ |
883 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 848 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
884 | /* connect headphone jack to dac1 */ | ||
885 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
886 | /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ | 849 | /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ |
887 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 850 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
888 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 851 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -901,8 +864,6 @@ static struct hda_verb stac92hd71bxx_analog_core_init[] = { | |||
901 | 864 | ||
902 | /* set master volume and direct control */ | 865 | /* set master volume and direct control */ |
903 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 866 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
904 | /* connect headphone jack to dac1 */ | ||
905 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
906 | /* unmute right and left channels for nodes 0x0a, 0xd */ | 867 | /* unmute right and left channels for nodes 0x0a, 0xd */ |
907 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 868 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
908 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 869 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -2747,70 +2708,53 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, | |||
2747 | return stac92xx_add_control_idx(spec, type, 0, name, val); | 2708 | return stac92xx_add_control_idx(spec, type, 0, name, val); |
2748 | } | 2709 | } |
2749 | 2710 | ||
2750 | /* flag inputs as additional dynamic lineouts */ | 2711 | /* check whether the line-input can be used as line-out */ |
2751 | static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) | 2712 | static hda_nid_t check_line_out_switch(struct hda_codec *codec) |
2752 | { | 2713 | { |
2753 | struct sigmatel_spec *spec = codec->spec; | 2714 | struct sigmatel_spec *spec = codec->spec; |
2754 | unsigned int wcaps, wtype; | 2715 | struct auto_pin_cfg *cfg = &spec->autocfg; |
2755 | int i, num_dacs = 0; | 2716 | hda_nid_t nid; |
2756 | 2717 | unsigned int pincap; | |
2757 | /* use the wcaps cache to count all DACs available for line-outs */ | ||
2758 | for (i = 0; i < codec->num_nodes; i++) { | ||
2759 | wcaps = codec->wcaps[i]; | ||
2760 | wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
2761 | 2718 | ||
2762 | if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) | 2719 | if (cfg->line_out_type != AUTO_PIN_LINE_OUT) |
2763 | num_dacs++; | 2720 | return 0; |
2764 | } | 2721 | nid = cfg->input_pins[AUTO_PIN_LINE]; |
2722 | pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | ||
2723 | if (pincap & AC_PINCAP_OUT) | ||
2724 | return nid; | ||
2725 | return 0; | ||
2726 | } | ||
2765 | 2727 | ||
2766 | snd_printdd("%s: total dac count=%d\n", __func__, num_dacs); | 2728 | /* check whether the mic-input can be used as line-out */ |
2767 | 2729 | static hda_nid_t check_mic_out_switch(struct hda_codec *codec) | |
2768 | switch (cfg->line_outs) { | 2730 | { |
2769 | case 3: | 2731 | struct sigmatel_spec *spec = codec->spec; |
2770 | /* add line-in as side */ | 2732 | struct auto_pin_cfg *cfg = &spec->autocfg; |
2771 | if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { | 2733 | unsigned int def_conf, pincap; |
2772 | cfg->line_out_pins[cfg->line_outs] = | 2734 | unsigned int mic_pin; |
2773 | cfg->input_pins[AUTO_PIN_LINE]; | 2735 | |
2774 | spec->line_switch = 1; | 2736 | if (cfg->line_out_type != AUTO_PIN_LINE_OUT) |
2775 | cfg->line_outs++; | 2737 | return 0; |
2776 | } | 2738 | mic_pin = AUTO_PIN_MIC; |
2777 | break; | 2739 | for (;;) { |
2778 | case 2: | 2740 | hda_nid_t nid = cfg->input_pins[mic_pin]; |
2779 | /* add line-in as clfe and mic as side */ | 2741 | def_conf = snd_hda_codec_read(codec, nid, 0, |
2780 | if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { | 2742 | AC_VERB_GET_CONFIG_DEFAULT, 0); |
2781 | cfg->line_out_pins[cfg->line_outs] = | 2743 | /* some laptops have an internal analog microphone |
2782 | cfg->input_pins[AUTO_PIN_LINE]; | 2744 | * which can't be used as a output */ |
2783 | spec->line_switch = 1; | 2745 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { |
2784 | cfg->line_outs++; | 2746 | pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); |
2785 | } | 2747 | if (pincap & AC_PINCAP_OUT) |
2786 | if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { | 2748 | return nid; |
2787 | cfg->line_out_pins[cfg->line_outs] = | ||
2788 | cfg->input_pins[AUTO_PIN_MIC]; | ||
2789 | spec->mic_switch = 1; | ||
2790 | cfg->line_outs++; | ||
2791 | } | ||
2792 | break; | ||
2793 | case 1: | ||
2794 | /* add line-in as surr and mic as clfe */ | ||
2795 | if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) { | ||
2796 | cfg->line_out_pins[cfg->line_outs] = | ||
2797 | cfg->input_pins[AUTO_PIN_LINE]; | ||
2798 | spec->line_switch = 1; | ||
2799 | cfg->line_outs++; | ||
2800 | } | ||
2801 | if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) { | ||
2802 | cfg->line_out_pins[cfg->line_outs] = | ||
2803 | cfg->input_pins[AUTO_PIN_MIC]; | ||
2804 | spec->mic_switch = 1; | ||
2805 | cfg->line_outs++; | ||
2806 | } | 2749 | } |
2807 | break; | 2750 | if (mic_pin == AUTO_PIN_MIC) |
2751 | mic_pin = AUTO_PIN_FRONT_MIC; | ||
2752 | else | ||
2753 | break; | ||
2808 | } | 2754 | } |
2809 | |||
2810 | return 0; | 2755 | return 0; |
2811 | } | 2756 | } |
2812 | 2757 | ||
2813 | |||
2814 | static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | 2758 | static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) |
2815 | { | 2759 | { |
2816 | int i; | 2760 | int i; |
@@ -2823,6 +2767,52 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | |||
2823 | return 0; | 2767 | return 0; |
2824 | } | 2768 | } |
2825 | 2769 | ||
2770 | static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | ||
2771 | { | ||
2772 | int i; | ||
2773 | if (is_in_dac_nids(spec, nid)) | ||
2774 | return 1; | ||
2775 | for (i = 0; i < spec->autocfg.hp_outs; i++) | ||
2776 | if (spec->hp_dacs[i] == nid) | ||
2777 | return 1; | ||
2778 | for (i = 0; i < spec->autocfg.speaker_outs; i++) | ||
2779 | if (spec->speaker_dacs[i] == nid) | ||
2780 | return 1; | ||
2781 | return 0; | ||
2782 | } | ||
2783 | |||
2784 | static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) | ||
2785 | { | ||
2786 | struct sigmatel_spec *spec = codec->spec; | ||
2787 | int j, conn_len; | ||
2788 | hda_nid_t conn[HDA_MAX_CONNECTIONS]; | ||
2789 | unsigned int wcaps, wtype; | ||
2790 | |||
2791 | conn_len = snd_hda_get_connections(codec, nid, conn, | ||
2792 | HDA_MAX_CONNECTIONS); | ||
2793 | for (j = 0; j < conn_len; j++) { | ||
2794 | wcaps = snd_hda_param_read(codec, conn[j], | ||
2795 | AC_PAR_AUDIO_WIDGET_CAP); | ||
2796 | wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
2797 | /* we check only analog outputs */ | ||
2798 | if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) | ||
2799 | continue; | ||
2800 | /* if this route has a free DAC, assign it */ | ||
2801 | if (!check_all_dac_nids(spec, conn[j])) { | ||
2802 | if (conn_len > 1) { | ||
2803 | /* select this DAC in the pin's input mux */ | ||
2804 | snd_hda_codec_write_cache(codec, nid, 0, | ||
2805 | AC_VERB_SET_CONNECT_SEL, j); | ||
2806 | } | ||
2807 | return conn[j]; | ||
2808 | } | ||
2809 | } | ||
2810 | return 0; | ||
2811 | } | ||
2812 | |||
2813 | static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid); | ||
2814 | static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid); | ||
2815 | |||
2826 | /* | 2816 | /* |
2827 | * Fill in the dac_nids table from the parsed pin configuration | 2817 | * Fill in the dac_nids table from the parsed pin configuration |
2828 | * This function only works when every pin in line_out_pins[] | 2818 | * This function only works when every pin in line_out_pins[] |
@@ -2830,31 +2820,17 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | |||
2830 | * codecs are not connected directly to a DAC, such as the 9200 | 2820 | * codecs are not connected directly to a DAC, such as the 9200 |
2831 | * and 9202/925x. For those, dac_nids[] must be hard-coded. | 2821 | * and 9202/925x. For those, dac_nids[] must be hard-coded. |
2832 | */ | 2822 | */ |
2833 | static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, | 2823 | static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) |
2834 | struct auto_pin_cfg *cfg) | ||
2835 | { | 2824 | { |
2836 | struct sigmatel_spec *spec = codec->spec; | 2825 | struct sigmatel_spec *spec = codec->spec; |
2837 | int i, j, conn_len = 0; | 2826 | struct auto_pin_cfg *cfg = &spec->autocfg; |
2838 | hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; | 2827 | int i; |
2839 | unsigned int wcaps, wtype; | 2828 | hda_nid_t nid, dac; |
2840 | 2829 | ||
2841 | for (i = 0; i < cfg->line_outs; i++) { | 2830 | for (i = 0; i < cfg->line_outs; i++) { |
2842 | nid = cfg->line_out_pins[i]; | 2831 | nid = cfg->line_out_pins[i]; |
2843 | conn_len = snd_hda_get_connections(codec, nid, conn, | 2832 | dac = get_unassigned_dac(codec, nid); |
2844 | HDA_MAX_CONNECTIONS); | 2833 | if (!dac) { |
2845 | for (j = 0; j < conn_len; j++) { | ||
2846 | wcaps = snd_hda_param_read(codec, conn[j], | ||
2847 | AC_PAR_AUDIO_WIDGET_CAP); | ||
2848 | wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | ||
2849 | if (wtype != AC_WID_AUD_OUT || | ||
2850 | (wcaps & AC_WCAP_DIGITAL)) | ||
2851 | continue; | ||
2852 | /* conn[j] is a DAC routed to this line-out */ | ||
2853 | if (!is_in_dac_nids(spec, conn[j])) | ||
2854 | break; | ||
2855 | } | ||
2856 | |||
2857 | if (j == conn_len) { | ||
2858 | if (spec->multiout.num_dacs > 0) { | 2834 | if (spec->multiout.num_dacs > 0) { |
2859 | /* we have already working output pins, | 2835 | /* we have already working output pins, |
2860 | * so let's drop the broken ones again | 2836 | * so let's drop the broken ones again |
@@ -2868,24 +2844,64 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, | |||
2868 | __func__, nid); | 2844 | __func__, nid); |
2869 | return -ENODEV; | 2845 | return -ENODEV; |
2870 | } | 2846 | } |
2847 | add_spec_dacs(spec, dac); | ||
2848 | } | ||
2871 | 2849 | ||
2872 | spec->multiout.dac_nids[i] = conn[j]; | 2850 | /* add line-in as output */ |
2873 | spec->multiout.num_dacs++; | 2851 | nid = check_line_out_switch(codec); |
2874 | if (conn_len > 1) { | 2852 | if (nid) { |
2875 | /* select this DAC in the pin's input mux */ | 2853 | dac = get_unassigned_dac(codec, nid); |
2876 | snd_hda_codec_write_cache(codec, nid, 0, | 2854 | if (dac) { |
2877 | AC_VERB_SET_CONNECT_SEL, j); | 2855 | snd_printdd("STAC: Add line-in 0x%x as output %d\n", |
2856 | nid, cfg->line_outs); | ||
2857 | cfg->line_out_pins[cfg->line_outs] = nid; | ||
2858 | cfg->line_outs++; | ||
2859 | spec->line_switch = nid; | ||
2860 | add_spec_dacs(spec, dac); | ||
2861 | } | ||
2862 | } | ||
2863 | /* add mic as output */ | ||
2864 | nid = check_mic_out_switch(codec); | ||
2865 | if (nid) { | ||
2866 | dac = get_unassigned_dac(codec, nid); | ||
2867 | if (dac) { | ||
2868 | snd_printdd("STAC: Add mic-in 0x%x as output %d\n", | ||
2869 | nid, cfg->line_outs); | ||
2870 | cfg->line_out_pins[cfg->line_outs] = nid; | ||
2871 | cfg->line_outs++; | ||
2872 | spec->mic_switch = nid; | ||
2873 | add_spec_dacs(spec, dac); | ||
2874 | } | ||
2875 | } | ||
2878 | 2876 | ||
2877 | for (i = 0; i < cfg->hp_outs; i++) { | ||
2878 | nid = cfg->hp_pins[i]; | ||
2879 | dac = get_unassigned_dac(codec, nid); | ||
2880 | if (dac) { | ||
2881 | if (!spec->multiout.hp_nid) | ||
2882 | spec->multiout.hp_nid = dac; | ||
2883 | else | ||
2884 | add_spec_extra_dacs(spec, dac); | ||
2879 | } | 2885 | } |
2886 | spec->hp_dacs[i] = dac; | ||
2880 | } | 2887 | } |
2881 | 2888 | ||
2882 | snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | 2889 | for (i = 0; i < cfg->speaker_outs; i++) { |
2890 | nid = cfg->speaker_pins[i]; | ||
2891 | dac = get_unassigned_dac(codec, nid); | ||
2892 | if (dac) | ||
2893 | add_spec_extra_dacs(spec, dac); | ||
2894 | spec->speaker_dacs[i] = dac; | ||
2895 | } | ||
2896 | |||
2897 | snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | ||
2883 | spec->multiout.num_dacs, | 2898 | spec->multiout.num_dacs, |
2884 | spec->multiout.dac_nids[0], | 2899 | spec->multiout.dac_nids[0], |
2885 | spec->multiout.dac_nids[1], | 2900 | spec->multiout.dac_nids[1], |
2886 | spec->multiout.dac_nids[2], | 2901 | spec->multiout.dac_nids[2], |
2887 | spec->multiout.dac_nids[3], | 2902 | spec->multiout.dac_nids[3], |
2888 | spec->multiout.dac_nids[4]); | 2903 | spec->multiout.dac_nids[4]); |
2904 | |||
2889 | return 0; | 2905 | return 0; |
2890 | } | 2906 | } |
2891 | 2907 | ||
@@ -2910,9 +2926,7 @@ static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_ | |||
2910 | 2926 | ||
2911 | static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) | 2927 | static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) |
2912 | { | 2928 | { |
2913 | if (!spec->multiout.hp_nid) | 2929 | if (spec->multiout.num_dacs > 4) { |
2914 | spec->multiout.hp_nid = nid; | ||
2915 | else if (spec->multiout.num_dacs > 4) { | ||
2916 | printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); | 2930 | printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); |
2917 | return 1; | 2931 | return 1; |
2918 | } else { | 2932 | } else { |
@@ -2922,13 +2936,17 @@ static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) | |||
2922 | return 0; | 2936 | return 0; |
2923 | } | 2937 | } |
2924 | 2938 | ||
2925 | static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | 2939 | static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid) |
2926 | { | 2940 | { |
2927 | if (is_in_dac_nids(spec, nid)) | 2941 | int i; |
2928 | return 1; | 2942 | for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) { |
2929 | if (spec->multiout.hp_nid == nid) | 2943 | if (!spec->multiout.extra_out_nid[i]) { |
2930 | return 1; | 2944 | spec->multiout.extra_out_nid[i] = nid; |
2931 | return 0; | 2945 | return 0; |
2946 | } | ||
2947 | } | ||
2948 | printk(KERN_WARNING "stac92xx: No space for extra DAC 0x%x\n", nid); | ||
2949 | return 1; | ||
2932 | } | 2950 | } |
2933 | 2951 | ||
2934 | /* add playback controls from the parsed DAC table */ | 2952 | /* add playback controls from the parsed DAC table */ |
@@ -2944,13 +2962,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
2944 | struct sigmatel_spec *spec = codec->spec; | 2962 | struct sigmatel_spec *spec = codec->spec; |
2945 | unsigned int wid_caps, pincap; | 2963 | unsigned int wid_caps, pincap; |
2946 | 2964 | ||
2947 | 2965 | for (i = 0; i < cfg->line_outs && spec->multiout.dac_nids[i]; i++) { | |
2948 | for (i = 0; i < cfg->line_outs && i < spec->multiout.num_dacs; i++) { | ||
2949 | if (!spec->multiout.dac_nids[i]) | ||
2950 | continue; | ||
2951 | |||
2952 | nid = spec->multiout.dac_nids[i]; | 2966 | nid = spec->multiout.dac_nids[i]; |
2953 | |||
2954 | if (i == 2) { | 2967 | if (i == 2) { |
2955 | /* Center/LFE */ | 2968 | /* Center/LFE */ |
2956 | err = create_controls(spec, "Center", nid, 1); | 2969 | err = create_controls(spec, "Center", nid, 1); |
@@ -2978,10 +2991,6 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
2978 | } | 2991 | } |
2979 | } | 2992 | } |
2980 | 2993 | ||
2981 | if ((spec->multiout.num_dacs - cfg->line_outs) > 0 && | ||
2982 | cfg->hp_outs == 1 && !spec->multiout.hp_nid) | ||
2983 | spec->multiout.hp_nid = nid; | ||
2984 | |||
2985 | if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { | 2994 | if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { |
2986 | err = stac92xx_add_control(spec, | 2995 | err = stac92xx_add_control(spec, |
2987 | STAC_CTL_WIDGET_HP_SWITCH, | 2996 | STAC_CTL_WIDGET_HP_SWITCH, |
@@ -2992,45 +3001,19 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
2992 | } | 3001 | } |
2993 | 3002 | ||
2994 | if (spec->line_switch) { | 3003 | if (spec->line_switch) { |
2995 | nid = cfg->input_pins[AUTO_PIN_LINE]; | 3004 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, |
2996 | pincap = snd_hda_param_read(codec, nid, | 3005 | "Line In as Output Switch", |
2997 | AC_PAR_PIN_CAP); | 3006 | spec->line_switch << 8); |
2998 | if (pincap & AC_PINCAP_OUT) { | 3007 | if (err < 0) |
2999 | err = stac92xx_add_control(spec, | 3008 | return err; |
3000 | STAC_CTL_WIDGET_IO_SWITCH, | ||
3001 | "Line In as Output Switch", nid << 8); | ||
3002 | if (err < 0) | ||
3003 | return err; | ||
3004 | } | ||
3005 | } | 3009 | } |
3006 | 3010 | ||
3007 | if (spec->mic_switch) { | 3011 | if (spec->mic_switch) { |
3008 | unsigned int def_conf; | 3012 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, |
3009 | unsigned int mic_pin = AUTO_PIN_MIC; | 3013 | "Mic as Output Switch", |
3010 | again: | 3014 | (spec->mic_switch << 8) | 1); |
3011 | nid = cfg->input_pins[mic_pin]; | 3015 | if (err < 0) |
3012 | def_conf = snd_hda_codec_read(codec, nid, 0, | 3016 | return err; |
3013 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
3014 | /* some laptops have an internal analog microphone | ||
3015 | * which can't be used as a output */ | ||
3016 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { | ||
3017 | pincap = snd_hda_param_read(codec, nid, | ||
3018 | AC_PAR_PIN_CAP); | ||
3019 | if (pincap & AC_PINCAP_OUT) { | ||
3020 | err = stac92xx_add_control(spec, | ||
3021 | STAC_CTL_WIDGET_IO_SWITCH, | ||
3022 | "Mic as Output Switch", (nid << 8) | 1); | ||
3023 | nid = snd_hda_codec_read(codec, nid, 0, | ||
3024 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | ||
3025 | if (!check_in_dac_nids(spec, nid)) | ||
3026 | add_spec_dacs(spec, nid); | ||
3027 | if (err < 0) | ||
3028 | return err; | ||
3029 | } | ||
3030 | } else if (mic_pin == AUTO_PIN_MIC) { | ||
3031 | mic_pin = AUTO_PIN_FRONT_MIC; | ||
3032 | goto again; | ||
3033 | } | ||
3034 | } | 3017 | } |
3035 | 3018 | ||
3036 | return 0; | 3019 | return 0; |
@@ -3042,55 +3025,39 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, | |||
3042 | { | 3025 | { |
3043 | struct sigmatel_spec *spec = codec->spec; | 3026 | struct sigmatel_spec *spec = codec->spec; |
3044 | hda_nid_t nid; | 3027 | hda_nid_t nid; |
3045 | int i, old_num_dacs, err; | 3028 | int i, err, nums; |
3046 | 3029 | ||
3047 | old_num_dacs = spec->multiout.num_dacs; | 3030 | nums = 0; |
3048 | for (i = 0; i < cfg->hp_outs; i++) { | 3031 | for (i = 0; i < cfg->hp_outs; i++) { |
3032 | static const char *pfxs[] = { | ||
3033 | "Headphone", "Headphone2", "Headphone3", | ||
3034 | }; | ||
3049 | unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]); | 3035 | unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]); |
3050 | if (wid_caps & AC_WCAP_UNSOL_CAP) | 3036 | if (wid_caps & AC_WCAP_UNSOL_CAP) |
3051 | spec->hp_detect = 1; | 3037 | spec->hp_detect = 1; |
3052 | nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0, | 3038 | if (nums >= ARRAY_SIZE(pfxs)) |
3053 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | ||
3054 | if (check_in_dac_nids(spec, nid)) | ||
3055 | nid = 0; | ||
3056 | if (! nid) | ||
3057 | continue; | 3039 | continue; |
3058 | add_spec_dacs(spec, nid); | 3040 | nid = spec->hp_dacs[i]; |
3059 | } | 3041 | if (!nid) |
3060 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
3061 | nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0, | ||
3062 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | ||
3063 | if (check_in_dac_nids(spec, nid)) | ||
3064 | nid = 0; | ||
3065 | if (! nid) | ||
3066 | continue; | ||
3067 | add_spec_dacs(spec, nid); | ||
3068 | } | ||
3069 | for (i = 0; i < cfg->line_outs; i++) { | ||
3070 | nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0, | ||
3071 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | ||
3072 | if (check_in_dac_nids(spec, nid)) | ||
3073 | nid = 0; | ||
3074 | if (! nid) | ||
3075 | continue; | 3042 | continue; |
3076 | add_spec_dacs(spec, nid); | 3043 | err = create_controls(spec, pfxs[nums++], nid, 3); |
3044 | if (err < 0) | ||
3045 | return err; | ||
3077 | } | 3046 | } |
3078 | for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { | 3047 | nums = 0; |
3048 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
3079 | static const char *pfxs[] = { | 3049 | static const char *pfxs[] = { |
3080 | "Speaker", "External Speaker", "Speaker2", | 3050 | "Speaker", "External Speaker", "Speaker2", |
3081 | }; | 3051 | }; |
3082 | err = create_controls(spec, pfxs[i - old_num_dacs], | 3052 | if (nums >= ARRAY_SIZE(pfxs)) |
3083 | spec->multiout.dac_nids[i], 3); | 3053 | continue; |
3084 | if (err < 0) | 3054 | nid = spec->speaker_dacs[i]; |
3085 | return err; | 3055 | if (!nid) |
3086 | } | 3056 | continue; |
3087 | if (spec->multiout.hp_nid) { | 3057 | err = create_controls(spec, pfxs[nums++], nid, 3); |
3088 | err = create_controls(spec, "Headphone", | ||
3089 | spec->multiout.hp_nid, 3); | ||
3090 | if (err < 0) | 3058 | if (err < 0) |
3091 | return err; | 3059 | return err; |
3092 | } | 3060 | } |
3093 | |||
3094 | return 0; | 3061 | return 0; |
3095 | } | 3062 | } |
3096 | 3063 | ||
@@ -3428,7 +3395,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3428 | { | 3395 | { |
3429 | struct sigmatel_spec *spec = codec->spec; | 3396 | struct sigmatel_spec *spec = codec->spec; |
3430 | int err; | 3397 | int err; |
3431 | int hp_speaker_swap = 0; | ||
3432 | 3398 | ||
3433 | if ((err = snd_hda_parse_pin_def_config(codec, | 3399 | if ((err = snd_hda_parse_pin_def_config(codec, |
3434 | &spec->autocfg, | 3400 | &spec->autocfg, |
@@ -3446,13 +3412,15 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3446 | * speaker_outs so that the following routines can handle | 3412 | * speaker_outs so that the following routines can handle |
3447 | * HP pins as primary outputs. | 3413 | * HP pins as primary outputs. |
3448 | */ | 3414 | */ |
3415 | snd_printdd("stac92xx: Enabling multi-HPs workaround\n"); | ||
3449 | memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins, | 3416 | memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins, |
3450 | sizeof(spec->autocfg.line_out_pins)); | 3417 | sizeof(spec->autocfg.line_out_pins)); |
3451 | spec->autocfg.speaker_outs = spec->autocfg.line_outs; | 3418 | spec->autocfg.speaker_outs = spec->autocfg.line_outs; |
3452 | memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins, | 3419 | memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins, |
3453 | sizeof(spec->autocfg.hp_pins)); | 3420 | sizeof(spec->autocfg.hp_pins)); |
3454 | spec->autocfg.line_outs = spec->autocfg.hp_outs; | 3421 | spec->autocfg.line_outs = spec->autocfg.hp_outs; |
3455 | hp_speaker_swap = 1; | 3422 | spec->autocfg.line_out_type = AUTO_PIN_HP_OUT; |
3423 | spec->autocfg.hp_outs = 0; | ||
3456 | } | 3424 | } |
3457 | if (spec->autocfg.mono_out_pin) { | 3425 | if (spec->autocfg.mono_out_pin) { |
3458 | int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & | 3426 | int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & |
@@ -3504,11 +3472,11 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3504 | AC_PINCTL_OUT_EN); | 3472 | AC_PINCTL_OUT_EN); |
3505 | } | 3473 | } |
3506 | 3474 | ||
3507 | if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) | 3475 | if (!spec->multiout.num_dacs) { |
3508 | return err; | 3476 | err = stac92xx_auto_fill_dac_nids(codec); |
3509 | if (spec->multiout.num_dacs == 0) | 3477 | if (err < 0) |
3510 | if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) | ||
3511 | return err; | 3478 | return err; |
3479 | } | ||
3512 | 3480 | ||
3513 | err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg); | 3481 | err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg); |
3514 | 3482 | ||
@@ -3546,19 +3514,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3546 | } | 3514 | } |
3547 | #endif | 3515 | #endif |
3548 | 3516 | ||
3549 | if (hp_speaker_swap == 1) { | ||
3550 | /* Restore the hp_outs and line_outs */ | ||
3551 | memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins, | ||
3552 | sizeof(spec->autocfg.line_out_pins)); | ||
3553 | spec->autocfg.hp_outs = spec->autocfg.line_outs; | ||
3554 | memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins, | ||
3555 | sizeof(spec->autocfg.speaker_pins)); | ||
3556 | spec->autocfg.line_outs = spec->autocfg.speaker_outs; | ||
3557 | memset(spec->autocfg.speaker_pins, 0, | ||
3558 | sizeof(spec->autocfg.speaker_pins)); | ||
3559 | spec->autocfg.speaker_outs = 0; | ||
3560 | } | ||
3561 | |||
3562 | err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); | 3517 | err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); |
3563 | 3518 | ||
3564 | if (err < 0) | 3519 | if (err < 0) |
@@ -3870,8 +3825,7 @@ static void stac92xx_power_down(struct hda_codec *codec) | |||
3870 | /* power down inactive DACs */ | 3825 | /* power down inactive DACs */ |
3871 | hda_nid_t *dac; | 3826 | hda_nid_t *dac; |
3872 | for (dac = spec->dac_list; *dac; dac++) | 3827 | for (dac = spec->dac_list; *dac; dac++) |
3873 | if (!is_in_dac_nids(spec, *dac) && | 3828 | if (!check_all_dac_nids(spec, *dac)) |
3874 | spec->multiout.hp_nid != *dac) | ||
3875 | snd_hda_codec_write(codec, *dac, 0, | 3829 | snd_hda_codec_write(codec, *dac, 0, |
3876 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | 3830 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); |
3877 | } | 3831 | } |
@@ -4055,10 +4009,7 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | |||
4055 | */ | 4009 | */ |
4056 | struct sigmatel_spec *spec = codec->spec; | 4010 | struct sigmatel_spec *spec = codec->spec; |
4057 | struct auto_pin_cfg *cfg = &spec->autocfg; | 4011 | struct auto_pin_cfg *cfg = &spec->autocfg; |
4058 | if ((nid == cfg->input_pins[AUTO_PIN_LINE] && | 4012 | if (nid == spec->line_switch || nid == spec->mic_switch) |
4059 | spec->line_switch) || | ||
4060 | (nid == cfg->input_pins[AUTO_PIN_MIC] && | ||
4061 | spec->mic_switch)) | ||
4062 | return; | 4013 | return; |
4063 | } | 4014 | } |
4064 | 4015 | ||
@@ -4100,11 +4051,9 @@ static int no_hp_sensing(struct sigmatel_spec *spec, int i) | |||
4100 | struct auto_pin_cfg *cfg = &spec->autocfg; | 4051 | struct auto_pin_cfg *cfg = &spec->autocfg; |
4101 | 4052 | ||
4102 | /* ignore sensing of shared line and mic jacks */ | 4053 | /* ignore sensing of shared line and mic jacks */ |
4103 | if (spec->line_switch && | 4054 | if (cfg->hp_pins[i] == spec->line_switch) |
4104 | cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE]) | ||
4105 | return 1; | 4055 | return 1; |
4106 | if (spec->mic_switch && | 4056 | if (cfg->hp_pins[i] == spec->mic_switch) |
4107 | cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC]) | ||
4108 | return 1; | 4057 | return 1; |
4109 | /* ignore if the pin is set as line-out */ | 4058 | /* ignore if the pin is set as line-out */ |
4110 | if (cfg->hp_pins[i] == spec->hp_switch) | 4059 | if (cfg->hp_pins[i] == spec->hp_switch) |
@@ -4515,6 +4464,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec) | |||
4515 | struct sigmatel_spec *spec; | 4464 | struct sigmatel_spec *spec; |
4516 | hda_nid_t conn[STAC92HD73_DAC_COUNT + 2]; | 4465 | hda_nid_t conn[STAC92HD73_DAC_COUNT + 2]; |
4517 | int err = 0; | 4466 | int err = 0; |
4467 | int num_dacs; | ||
4518 | 4468 | ||
4519 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4469 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4520 | if (spec == NULL) | 4470 | if (spec == NULL) |
@@ -4541,33 +4491,29 @@ again: | |||
4541 | return err; | 4491 | return err; |
4542 | } | 4492 | } |
4543 | 4493 | ||
4544 | spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a, | 4494 | num_dacs = snd_hda_get_connections(codec, 0x0a, |
4545 | conn, STAC92HD73_DAC_COUNT + 2) - 1; | 4495 | conn, STAC92HD73_DAC_COUNT + 2) - 1; |
4546 | 4496 | ||
4547 | if (spec->multiout.num_dacs < 0) { | 4497 | if (num_dacs < 3 || num_dacs > 5) { |
4548 | printk(KERN_WARNING "hda_codec: Could not determine " | 4498 | printk(KERN_WARNING "hda_codec: Could not determine " |
4549 | "number of channels defaulting to DAC count\n"); | 4499 | "number of channels defaulting to DAC count\n"); |
4550 | spec->multiout.num_dacs = STAC92HD73_DAC_COUNT; | 4500 | num_dacs = STAC92HD73_DAC_COUNT; |
4551 | } | 4501 | } |
4552 | 4502 | switch (num_dacs) { | |
4553 | switch (spec->multiout.num_dacs) { | ||
4554 | case 0x3: /* 6 Channel */ | 4503 | case 0x3: /* 6 Channel */ |
4555 | spec->multiout.hp_nid = 0x17; | ||
4556 | spec->mixer = stac92hd73xx_6ch_mixer; | 4504 | spec->mixer = stac92hd73xx_6ch_mixer; |
4557 | spec->init = stac92hd73xx_6ch_core_init; | 4505 | spec->init = stac92hd73xx_6ch_core_init; |
4558 | break; | 4506 | break; |
4559 | case 0x4: /* 8 Channel */ | 4507 | case 0x4: /* 8 Channel */ |
4560 | spec->multiout.hp_nid = 0x18; | ||
4561 | spec->mixer = stac92hd73xx_8ch_mixer; | 4508 | spec->mixer = stac92hd73xx_8ch_mixer; |
4562 | spec->init = stac92hd73xx_8ch_core_init; | 4509 | spec->init = stac92hd73xx_8ch_core_init; |
4563 | break; | 4510 | break; |
4564 | case 0x5: /* 10 Channel */ | 4511 | case 0x5: /* 10 Channel */ |
4565 | spec->multiout.hp_nid = 0x19; | ||
4566 | spec->mixer = stac92hd73xx_10ch_mixer; | 4512 | spec->mixer = stac92hd73xx_10ch_mixer; |
4567 | spec->init = stac92hd73xx_10ch_core_init; | 4513 | spec->init = stac92hd73xx_10ch_core_init; |
4568 | }; | 4514 | } |
4515 | spec->multiout.dac_nids = spec->dac_nids; | ||
4569 | 4516 | ||
4570 | spec->multiout.dac_nids = stac92hd73xx_dac_nids; | ||
4571 | spec->aloopback_mask = 0x01; | 4517 | spec->aloopback_mask = 0x01; |
4572 | spec->aloopback_shift = 8; | 4518 | spec->aloopback_shift = 8; |
4573 | 4519 | ||
@@ -4598,9 +4544,8 @@ again: | |||
4598 | spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; | 4544 | spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; |
4599 | spec->eapd_switch = 0; | 4545 | spec->eapd_switch = 0; |
4600 | spec->num_amps = 1; | 4546 | spec->num_amps = 1; |
4601 | spec->multiout.hp_nid = 0; /* dual HPs */ | ||
4602 | 4547 | ||
4603 | if (!spec->init) | 4548 | if (spec->board_config != STAC_DELL_EQ) |
4604 | spec->init = dell_m6_core_init; | 4549 | spec->init = dell_m6_core_init; |
4605 | switch (spec->board_config) { | 4550 | switch (spec->board_config) { |
4606 | case STAC_DELL_M6_AMIC: /* Analog Mics */ | 4551 | case STAC_DELL_M6_AMIC: /* Analog Mics */ |
@@ -4691,17 +4636,15 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
4691 | spec->pwr_nids = stac92hd83xxx_pwr_nids; | 4636 | spec->pwr_nids = stac92hd83xxx_pwr_nids; |
4692 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; | 4637 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; |
4693 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | 4638 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); |
4694 | spec->multiout.dac_nids = stac92hd83xxx_dac_nids; | 4639 | spec->multiout.dac_nids = spec->dac_nids; |
4695 | 4640 | ||
4696 | spec->init = stac92hd83xxx_core_init; | 4641 | spec->init = stac92hd83xxx_core_init; |
4697 | switch (codec->vendor_id) { | 4642 | switch (codec->vendor_id) { |
4698 | case 0x111d7605: | 4643 | case 0x111d7605: |
4699 | spec->multiout.num_dacs = STAC92HD81_DAC_COUNT; | ||
4700 | break; | 4644 | break; |
4701 | default: | 4645 | default: |
4702 | spec->num_pwrs--; | 4646 | spec->num_pwrs--; |
4703 | spec->init++; /* switch to config #2 */ | 4647 | spec->init++; /* switch to config #2 */ |
4704 | spec->multiout.num_dacs = STAC92HD83_DAC_COUNT; | ||
4705 | } | 4648 | } |
4706 | 4649 | ||
4707 | spec->mixer = stac92hd83xxx_mixer; | 4650 | spec->mixer = stac92hd83xxx_mixer; |
@@ -4892,9 +4835,7 @@ again: | |||
4892 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | 4835 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); |
4893 | }; | 4836 | }; |
4894 | 4837 | ||
4895 | spec->multiout.num_dacs = 1; | 4838 | spec->multiout.dac_nids = spec->dac_nids; |
4896 | spec->multiout.hp_nid = 0x11; | ||
4897 | spec->multiout.dac_nids = stac92hd71bxx_dac_nids; | ||
4898 | if (spec->dinput_mux) | 4839 | if (spec->dinput_mux) |
4899 | spec->private_dimux.num_items += | 4840 | spec->private_dimux.num_items += |
4900 | spec->num_dmics - | 4841 | spec->num_dmics - |