aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_sigmatel.c121
1 files changed, 87 insertions, 34 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index ebf7dde92d59..93ae9c250767 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1070,11 +1070,23 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char
1070static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) 1070static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg)
1071{ 1071{
1072 struct sigmatel_spec *spec = codec->spec; 1072 struct sigmatel_spec *spec = codec->spec;
1073 unsigned int wcaps, wtype;
1074 int i, num_dacs = 0;
1075
1076 /* use the wcaps cache to count all DACs available for line-outs */
1077 for (i = 0; i < codec->num_nodes; i++) {
1078 wcaps = codec->wcaps[i];
1079 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1080 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL))
1081 num_dacs++;
1082 }
1073 1083
1084 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs);
1085
1074 switch (cfg->line_outs) { 1086 switch (cfg->line_outs) {
1075 case 3: 1087 case 3:
1076 /* add line-in as side */ 1088 /* add line-in as side */
1077 if (cfg->input_pins[AUTO_PIN_LINE]) { 1089 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) {
1078 cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE]; 1090 cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE];
1079 spec->line_switch = 1; 1091 spec->line_switch = 1;
1080 cfg->line_outs++; 1092 cfg->line_outs++;
@@ -1082,12 +1094,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
1082 break; 1094 break;
1083 case 2: 1095 case 2:
1084 /* add line-in as clfe and mic as side */ 1096 /* add line-in as clfe and mic as side */
1085 if (cfg->input_pins[AUTO_PIN_LINE]) { 1097 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) {
1086 cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE]; 1098 cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE];
1087 spec->line_switch = 1; 1099 spec->line_switch = 1;
1088 cfg->line_outs++; 1100 cfg->line_outs++;
1089 } 1101 }
1090 if (cfg->input_pins[AUTO_PIN_MIC]) { 1102 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) {
1091 cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC]; 1103 cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC];
1092 spec->mic_switch = 1; 1104 spec->mic_switch = 1;
1093 cfg->line_outs++; 1105 cfg->line_outs++;
@@ -1095,12 +1107,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
1095 break; 1107 break;
1096 case 1: 1108 case 1:
1097 /* add line-in as surr and mic as clfe */ 1109 /* add line-in as surr and mic as clfe */
1098 if (cfg->input_pins[AUTO_PIN_LINE]) { 1110 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
1099 cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE]; 1111 cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE];
1100 spec->line_switch = 1; 1112 spec->line_switch = 1;
1101 cfg->line_outs++; 1113 cfg->line_outs++;
1102 } 1114 }
1103 if (cfg->input_pins[AUTO_PIN_MIC]) { 1115 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
1104 cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC]; 1116 cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC];
1105 spec->mic_switch = 1; 1117 spec->mic_switch = 1;
1106 cfg->line_outs++; 1118 cfg->line_outs++;
@@ -1111,33 +1123,76 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf
1111 return 0; 1123 return 0;
1112} 1124}
1113 1125
1126
1127static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1128{
1129 int i;
1130
1131 for (i = 0; i < spec->multiout.num_dacs; i++) {
1132 if (spec->multiout.dac_nids[i] == nid)
1133 return 1;
1134 }
1135
1136 return 0;
1137}
1138
1114/* 1139/*
1115 * XXX The line_out pin widget connection list may not be set to the 1140 * Fill in the dac_nids table from the parsed pin configuration
1116 * desired DAC nid. This is the case on 927x where ports A and B can 1141 * This function only works when every pin in line_out_pins[]
1117 * be routed to several DACs. 1142 * contains atleast one DAC in its connection list. Some 92xx
1118 * 1143 * codecs are not connected directly to a DAC, such as the 9200
1119 * This requires an analysis of the line-out/hp pin configuration 1144 * and 9202/925x. For those, dac_nids[] must be hard-coded.
1120 * to provide a best fit for pin/DAC configurations that are routable.
1121 * For now, 927x DAC4 is not supported and 927x DAC1 output to ports
1122 * A and B is not supported.
1123 */ 1145 */
1124/* fill in the dac_nids table from the parsed pin configuration */
1125static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, 1146static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
1126 const struct auto_pin_cfg *cfg) 1147 const struct auto_pin_cfg *cfg)
1127{ 1148{
1128 struct sigmatel_spec *spec = codec->spec; 1149 struct sigmatel_spec *spec = codec->spec;
1129 hda_nid_t nid; 1150 int i, j, conn_len = 0;
1130 int i; 1151 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS];
1131 1152 unsigned int wcaps, wtype;
1132 /* check the pins hardwired to audio widget */ 1153
1133 for (i = 0; i < cfg->line_outs; i++) { 1154 for (i = 0; i < cfg->line_outs; i++) {
1134 nid = cfg->line_out_pins[i]; 1155 nid = cfg->line_out_pins[i];
1135 spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0, 1156 conn_len = snd_hda_get_connections(codec, nid, conn,
1136 AC_VERB_GET_CONNECT_LIST, 0) & 0xff; 1157 HDA_MAX_CONNECTIONS);
1137 } 1158 for (j = 0; j < conn_len; j++) {
1159 wcaps = snd_hda_param_read(codec, conn[j],
1160 AC_PAR_AUDIO_WIDGET_CAP);
1161 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
1162
1163 if (wtype != AC_WID_AUD_OUT ||
1164 (wcaps & AC_WCAP_DIGITAL))
1165 continue;
1166 /* conn[j] is a DAC routed to this line-out */
1167 if (!is_in_dac_nids(spec, conn[j]))
1168 break;
1169 }
1170
1171 if (j == conn_len) {
1172 /* error out, no available DAC found */
1173 snd_printk(KERN_ERR
1174 "%s: No available DAC for pin 0x%x\n",
1175 __func__, nid);
1176 return -ENODEV;
1177 }
1178
1179 spec->multiout.dac_nids[i] = conn[j];
1180 spec->multiout.num_dacs++;
1181 if (conn_len > 1) {
1182 /* select this DAC in the pin's input mux */
1183 snd_hda_codec_write(codec, nid, 0,
1184 AC_VERB_SET_CONNECT_SEL, j);
1138 1185
1139 spec->multiout.num_dacs = cfg->line_outs; 1186 }
1187 }
1140 1188
1189 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
1190 spec->multiout.num_dacs,
1191 spec->multiout.dac_nids[0],
1192 spec->multiout.dac_nids[1],
1193 spec->multiout.dac_nids[2],
1194 spec->multiout.dac_nids[3],
1195 spec->multiout.dac_nids[4]);
1141 return 0; 1196 return 0;
1142} 1197}
1143 1198
@@ -1204,12 +1259,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec,
1204 1259
1205static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) 1260static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
1206{ 1261{
1207 int i; 1262 if (is_in_dac_nids(spec, nid))
1208 1263 return 1;
1209 for (i = 0; i < spec->multiout.num_dacs; i++) {
1210 if (spec->multiout.dac_nids[i] == nid)
1211 return 1;
1212 }
1213 if (spec->multiout.hp_nid == nid) 1264 if (spec->multiout.hp_nid == nid)
1214 return 1; 1265 return 1;
1215 return 0; 1266 return 0;
@@ -1251,12 +1302,10 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
1251 add_spec_dacs(spec, nid); 1302 add_spec_dacs(spec, nid);
1252 } 1303 }
1253 for (i = 0; i < cfg->speaker_outs; i++) { 1304 for (i = 0; i < cfg->speaker_outs; i++) {
1254 nid = snd_hda_codec_read(codec, cfg->speaker_pins[0], 0, 1305 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
1255 AC_VERB_GET_CONNECT_LIST, 0) & 0xff; 1306 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
1256 if (check_in_dac_nids(spec, nid)) 1307 if (check_in_dac_nids(spec, nid))
1257 nid = 0; 1308 nid = 0;
1258 if (check_in_dac_nids(spec, nid))
1259 nid = 0;
1260 if (! nid) 1309 if (! nid)
1261 continue; 1310 continue;
1262 add_spec_dacs(spec, nid); 1311 add_spec_dacs(spec, nid);
@@ -1370,7 +1419,7 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const
1370 imux->num_items++; 1419 imux->num_items++;
1371 } 1420 }
1372 1421
1373 if (imux->num_items == 1) { 1422 if (imux->num_items) {
1374 /* 1423 /*
1375 * Set the current input for the muxes. 1424 * Set the current input for the muxes.
1376 * The STAC9221 has two input muxes with identical source 1425 * The STAC9221 has two input muxes with identical source
@@ -1690,8 +1739,12 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
1690{ 1739{
1691 unsigned int pin_ctl = snd_hda_codec_read(codec, nid, 1740 unsigned int pin_ctl = snd_hda_codec_read(codec, nid,
1692 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); 1741 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00);
1693 if (flag == AC_PINCTL_OUT_EN && (pin_ctl & AC_PINCTL_IN_EN)) 1742
1694 return; 1743 /* if setting pin direction bits, clear the current
1744 direction bits first */
1745 if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))
1746 pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
1747
1695 snd_hda_codec_write(codec, nid, 0, 1748 snd_hda_codec_write(codec, nid, 0,
1696 AC_VERB_SET_PIN_WIDGET_CONTROL, 1749 AC_VERB_SET_PIN_WIDGET_CONTROL,
1697 pin_ctl | flag); 1750 pin_ctl | flag);