aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_sigmatel.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2006-03-21 05:24:42 -0500
committerJaroslav Kysela <perex@suse.cz>2006-03-22 04:40:14 -0500
commit82bc955f6379135e6ce35ff90c7ac411fd412c4c (patch)
tree314610afb5a469ac6a5a9f4d5e947436bb2c0538 /sound/pci/hda/patch_sigmatel.c
parent19739fef0203d2f3eecc9c4b1ef25b57d85f2b30 (diff)
[ALSA] hda-codec - Fix BIOS auto-configuration
Modules: HDA Codec driver,HDA generic driver - Fix autoconfig speaker/hp detection Now it allows multiple speaker pins (e.g. Dell laptops have such config) - Use speaker or hp pins if no line-outs are available This fixes the silence output on recent Dell laptops with STAC9200 (ALSA bug#1843) - Fix analog/realtek/sigmatel autoconfig parser Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r--sound/pci/hda/patch_sigmatel.c84
1 files changed, 58 insertions, 26 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 240958df26ce..b56ca4019392 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -51,6 +51,7 @@ struct sigmatel_spec {
51 unsigned int line_switch: 1; 51 unsigned int line_switch: 1;
52 unsigned int mic_switch: 1; 52 unsigned int mic_switch: 1;
53 unsigned int alt_switch: 1; 53 unsigned int alt_switch: 1;
54 unsigned int hp_detect: 1;
54 55
55 /* playback */ 56 /* playback */
56 struct hda_multi_out multiout; 57 struct hda_multi_out multiout;
@@ -697,13 +698,7 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct aut
697 AC_VERB_GET_CONNECT_LIST, 0) & 0xff; 698 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
698 } 699 }
699 700
700 if (cfg->line_outs) 701 spec->multiout.num_dacs = cfg->line_outs;
701 spec->multiout.num_dacs = cfg->line_outs;
702 else if (cfg->hp_pin) {
703 spec->multiout.dac_nids[0] = snd_hda_codec_read(codec, cfg->hp_pin, 0,
704 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
705 spec->multiout.num_dacs = 1;
706 }
707 702
708 return 0; 703 return 0;
709} 704}
@@ -772,11 +767,13 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin
772 return 0; 767 return 0;
773 768
774 wid_caps = get_wcaps(codec, pin); 769 wid_caps = get_wcaps(codec, pin);
775 if (wid_caps & AC_WCAP_UNSOL_CAP) 770 if (wid_caps & AC_WCAP_UNSOL_CAP) {
776 /* Enable unsolicited responses on the HP widget */ 771 /* Enable unsolicited responses on the HP widget */
777 snd_hda_codec_write(codec, pin, 0, 772 snd_hda_codec_write(codec, pin, 0,
778 AC_VERB_SET_UNSOLICITED_ENABLE, 773 AC_VERB_SET_UNSOLICITED_ENABLE,
779 STAC_UNSOL_ENABLE); 774 STAC_UNSOL_ENABLE);
775 spec->hp_detect = 1;
776 }
780 777
781 nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; 778 nid = snd_hda_codec_read(codec, pin, 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
782 for (i = 0; i < cfg->line_outs; i++) { 779 for (i = 0; i < cfg->line_outs; i++) {
@@ -810,9 +807,6 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
810 for (i = 0; i < AUTO_PIN_LAST; i++) { 807 for (i = 0; i < AUTO_PIN_LAST; i++) {
811 int index = -1; 808 int index = -1;
812 if (cfg->input_pins[i]) { 809 if (cfg->input_pins[i]) {
813 /* Enable active pin widget as an input */
814 stac92xx_auto_set_pinctl(codec, cfg->input_pins[i], AC_PINCTL_IN_EN);
815
816 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 810 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
817 811
818 for (j=0; j<spec->num_muxes; j++) { 812 for (j=0; j<spec->num_muxes; j++) {
@@ -861,10 +855,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
861 855
862 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) 856 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
863 return err; 857 return err;
864 if (! spec->autocfg.line_outs && ! spec->autocfg.hp_pin) 858 if (! spec->autocfg.line_outs)
865 return 0; /* can't find valid pin config */ 859 return 0; /* can't find valid pin config */
866 stac92xx_auto_init_multi_out(codec);
867 stac92xx_auto_init_hp_out(codec);
868 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) 860 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0)
869 return err; 861 return err;
870 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) 862 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
@@ -879,14 +871,10 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
879 if (spec->multiout.max_channels > 2) 871 if (spec->multiout.max_channels > 2)
880 spec->surr_switch = 1; 872 spec->surr_switch = 1;
881 873
882 if (spec->autocfg.dig_out_pin) { 874 if (spec->autocfg.dig_out_pin)
883 spec->multiout.dig_out_nid = dig_out; 875 spec->multiout.dig_out_nid = dig_out;
884 stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); 876 if (spec->autocfg.dig_in_pin)
885 }
886 if (spec->autocfg.dig_in_pin) {
887 spec->dig_in_nid = dig_in; 877 spec->dig_in_nid = dig_in;
888 stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN);
889 }
890 878
891 if (spec->kctl_alloc) 879 if (spec->kctl_alloc)
892 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 880 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
@@ -896,6 +884,29 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
896 return 1; 884 return 1;
897} 885}
898 886
887/* add playback controls for HP output */
888static int stac9200_auto_create_hp_ctls(struct hda_codec *codec,
889 struct auto_pin_cfg *cfg)
890{
891 struct sigmatel_spec *spec = codec->spec;
892 hda_nid_t pin = cfg->hp_pin;
893 unsigned int wid_caps;
894
895 if (! pin)
896 return 0;
897
898 wid_caps = get_wcaps(codec, pin);
899 if (wid_caps & AC_WCAP_UNSOL_CAP) {
900 /* Enable unsolicited responses on the HP widget */
901 snd_hda_codec_write(codec, pin, 0,
902 AC_VERB_SET_UNSOLICITED_ENABLE,
903 STAC_UNSOL_ENABLE);
904 spec->hp_detect = 1;
905 }
906
907 return 0;
908}
909
899static int stac9200_parse_auto_config(struct hda_codec *codec) 910static int stac9200_parse_auto_config(struct hda_codec *codec)
900{ 911{
901 struct sigmatel_spec *spec = codec->spec; 912 struct sigmatel_spec *spec = codec->spec;
@@ -907,14 +918,13 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
907 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) 918 if ((err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
908 return err; 919 return err;
909 920
910 if (spec->autocfg.dig_out_pin) { 921 if ((err = stac9200_auto_create_hp_ctls(codec, &spec->autocfg)) < 0)
922 return err;
923
924 if (spec->autocfg.dig_out_pin)
911 spec->multiout.dig_out_nid = 0x05; 925 spec->multiout.dig_out_nid = 0x05;
912 stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_out_pin, AC_PINCTL_OUT_EN); 926 if (spec->autocfg.dig_in_pin)
913 }
914 if (spec->autocfg.dig_in_pin) {
915 spec->dig_in_nid = 0x04; 927 spec->dig_in_nid = 0x04;
916 stac92xx_auto_set_pinctl(codec, spec->autocfg.dig_in_pin, AC_PINCTL_IN_EN);
917 }
918 928
919 if (spec->kctl_alloc) 929 if (spec->kctl_alloc)
920 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 930 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
@@ -927,9 +937,31 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
927static int stac92xx_init(struct hda_codec *codec) 937static int stac92xx_init(struct hda_codec *codec)
928{ 938{
929 struct sigmatel_spec *spec = codec->spec; 939 struct sigmatel_spec *spec = codec->spec;
940 struct auto_pin_cfg *cfg = &spec->autocfg;
941 int i;
930 942
931 snd_hda_sequence_write(codec, spec->init); 943 snd_hda_sequence_write(codec, spec->init);
932 944
945 /* set up pins */
946 if (spec->hp_detect) {
947 /* fake event to set up pins */
948 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26);
949 } else {
950 stac92xx_auto_init_multi_out(codec);
951 stac92xx_auto_init_hp_out(codec);
952 }
953 for (i = 0; i < AUTO_PIN_LAST; i++) {
954 if (cfg->input_pins[i])
955 stac92xx_auto_set_pinctl(codec, cfg->input_pins[i],
956 AC_PINCTL_IN_EN);
957 }
958 if (cfg->dig_out_pin)
959 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
960 AC_PINCTL_OUT_EN);
961 if (cfg->dig_in_pin)
962 stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
963 AC_PINCTL_IN_EN);
964
933 return 0; 965 return 0;
934} 966}
935 967