diff options
author | Takashi Iwai <tiwai@suse.de> | 2005-11-21 10:33:22 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-01-03 06:29:27 -0500 |
commit | 54d174031576a2855c49611d83d4946bde81b504 (patch) | |
tree | 6bdcefaccb78bddfa1a3ea7b429e1178b479999d /sound/pci/hda | |
parent | 1b98ea4791892399d8c23c93e117567eeff38887 (diff) |
[ALSA] hda-codec - Fix connection list parsing
Modules: HDA Codec driver,HDA generic driver
- Fix connection list parsing (with ranged flag).
- Increase the max number of connections
- Introduce widget capabilities cache
- Power up/down widgets at init, suspend and resume
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 155 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 13 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 14 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 3 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 25 |
5 files changed, 140 insertions, 70 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 7f4e19951bae..402ce00c6a13 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -155,8 +155,9 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
155 | hda_nid_t *conn_list, int max_conns) | 155 | hda_nid_t *conn_list, int max_conns) |
156 | { | 156 | { |
157 | unsigned int parm; | 157 | unsigned int parm; |
158 | int i, j, conn_len, num_tupples, conns; | 158 | int i, conn_len, conns; |
159 | unsigned int shift, num_elems, mask; | 159 | unsigned int shift, num_elems, mask; |
160 | hda_nid_t prev_nid; | ||
160 | 161 | ||
161 | snd_assert(conn_list && max_conns > 0, return -EINVAL); | 162 | snd_assert(conn_list && max_conns > 0, return -EINVAL); |
162 | 163 | ||
@@ -171,7 +172,6 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
171 | num_elems = 4; | 172 | num_elems = 4; |
172 | } | 173 | } |
173 | conn_len = parm & AC_CLIST_LENGTH; | 174 | conn_len = parm & AC_CLIST_LENGTH; |
174 | num_tupples = num_elems / 2; | ||
175 | mask = (1 << (shift-1)) - 1; | 175 | mask = (1 << (shift-1)) - 1; |
176 | 176 | ||
177 | if (! conn_len) | 177 | if (! conn_len) |
@@ -186,40 +186,38 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
186 | 186 | ||
187 | /* multi connection */ | 187 | /* multi connection */ |
188 | conns = 0; | 188 | conns = 0; |
189 | for (i = 0; i < conn_len; i += num_elems) { | 189 | prev_nid = 0; |
190 | parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, i); | 190 | for (i = 0; i < conn_len; i++) { |
191 | for (j = 0; j < num_tupples; j++) { | 191 | int range_val; |
192 | int range_val; | 192 | hda_nid_t val, n; |
193 | hda_nid_t val1, val2, n; | 193 | |
194 | range_val = parm & (1 << (shift-1)); /* ranges */ | 194 | if (i % num_elems == 0) |
195 | val1 = parm & mask; | 195 | parm = snd_hda_codec_read(codec, nid, 0, |
196 | parm >>= shift; | 196 | AC_VERB_GET_CONNECT_LIST, i); |
197 | val2 = parm & mask; | 197 | range_val = !! (parm & (1 << (shift-1))); /* ranges */ |
198 | parm >>= shift; | 198 | val = parm & mask; |
199 | if (range_val) { | 199 | parm >>= shift; |
200 | /* ranges between val1 and val2 */ | 200 | if (range_val) { |
201 | if (val1 > val2) { | 201 | /* ranges between the previous and this one */ |
202 | snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", val1, val2); | 202 | if (! prev_nid || prev_nid >= val) { |
203 | continue; | 203 | snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", prev_nid, val); |
204 | } | 204 | continue; |
205 | for (n = val1; n <= val2; n++) { | 205 | } |
206 | if (conns >= max_conns) | 206 | for (n = prev_nid + 1; n <= val; n++) { |
207 | return -EINVAL; | 207 | if (conns >= max_conns) { |
208 | conn_list[conns++] = n; | 208 | snd_printk(KERN_ERR "Too many connections\n"); |
209 | } | ||
210 | } else { | ||
211 | if (! val1) | ||
212 | break; | ||
213 | if (conns >= max_conns) | ||
214 | return -EINVAL; | ||
215 | conn_list[conns++] = val1; | ||
216 | if (! val2) | ||
217 | break; | ||
218 | if (conns >= max_conns) | ||
219 | return -EINVAL; | 209 | return -EINVAL; |
220 | conn_list[conns++] = val2; | 210 | } |
211 | conn_list[conns++] = n; | ||
221 | } | 212 | } |
213 | } else { | ||
214 | if (conns >= max_conns) { | ||
215 | snd_printk(KERN_ERR "Too many connections\n"); | ||
216 | return -EINVAL; | ||
217 | } | ||
218 | conn_list[conns++] = val; | ||
222 | } | 219 | } |
220 | prev_nid = val; | ||
223 | } | 221 | } |
224 | return conns; | 222 | return conns; |
225 | } | 223 | } |
@@ -456,6 +454,27 @@ static void setup_fg_nodes(struct hda_codec *codec) | |||
456 | } | 454 | } |
457 | 455 | ||
458 | /* | 456 | /* |
457 | * read widget caps for each widget and store in cache | ||
458 | */ | ||
459 | static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) | ||
460 | { | ||
461 | int i; | ||
462 | hda_nid_t nid; | ||
463 | |||
464 | codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node, | ||
465 | &codec->start_nid); | ||
466 | codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL); | ||
467 | if (! codec->wcaps) | ||
468 | return -ENOMEM; | ||
469 | nid = codec->start_nid; | ||
470 | for (i = 0; i < codec->num_nodes; i++, nid++) | ||
471 | codec->wcaps[i] = snd_hda_param_read(codec, nid, | ||
472 | AC_PAR_AUDIO_WIDGET_CAP); | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | |||
477 | /* | ||
459 | * codec destructor | 478 | * codec destructor |
460 | */ | 479 | */ |
461 | static void snd_hda_codec_free(struct hda_codec *codec) | 480 | static void snd_hda_codec_free(struct hda_codec *codec) |
@@ -467,6 +486,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
467 | if (codec->patch_ops.free) | 486 | if (codec->patch_ops.free) |
468 | codec->patch_ops.free(codec); | 487 | codec->patch_ops.free(codec); |
469 | kfree(codec->amp_info); | 488 | kfree(codec->amp_info); |
489 | kfree(codec->wcaps); | ||
470 | kfree(codec); | 490 | kfree(codec); |
471 | } | 491 | } |
472 | 492 | ||
@@ -520,6 +540,12 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, | |||
520 | return -ENODEV; | 540 | return -ENODEV; |
521 | } | 541 | } |
522 | 542 | ||
543 | if (read_widget_caps(codec, codec->afg ? codec->afg : codec->mfg) < 0) { | ||
544 | snd_printk(KERN_ERR "hda_codec: cannot malloc\n"); | ||
545 | snd_hda_codec_free(codec); | ||
546 | return -ENOMEM; | ||
547 | } | ||
548 | |||
523 | if (! codec->subsystem_id) { | 549 | if (! codec->subsystem_id) { |
524 | hda_nid_t nid = codec->afg ? codec->afg : codec->mfg; | 550 | hda_nid_t nid = codec->afg ? codec->afg : codec->mfg; |
525 | codec->subsystem_id = snd_hda_codec_read(codec, nid, 0, | 551 | codec->subsystem_id = snd_hda_codec_read(codec, nid, 0, |
@@ -647,7 +673,7 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) | |||
647 | if (! info) | 673 | if (! info) |
648 | return 0; | 674 | return 0; |
649 | if (! (info->status & INFO_AMP_CAPS)) { | 675 | if (! (info->status & INFO_AMP_CAPS)) { |
650 | if (!(snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP) & AC_WCAP_AMP_OVRD)) | 676 | if (! (get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) |
651 | nid = codec->afg; | 677 | nid = codec->afg; |
652 | info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ? | 678 | info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ? |
653 | AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP); | 679 | AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP); |
@@ -1195,6 +1221,31 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) | |||
1195 | } | 1221 | } |
1196 | 1222 | ||
1197 | 1223 | ||
1224 | /* | ||
1225 | * set power state of the codec | ||
1226 | */ | ||
1227 | static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | ||
1228 | unsigned int power_state) | ||
1229 | { | ||
1230 | hda_nid_t nid, nid_start; | ||
1231 | int nodes; | ||
1232 | |||
1233 | snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE, | ||
1234 | power_state); | ||
1235 | |||
1236 | nodes = snd_hda_get_sub_nodes(codec, fg, &nid_start); | ||
1237 | for (nid = nid_start; nid < nodes + nid_start; nid++) { | ||
1238 | if (get_wcaps(codec, nid) & AC_WCAP_POWER) | ||
1239 | snd_hda_codec_write(codec, nid, 0, | ||
1240 | AC_VERB_SET_POWER_STATE, | ||
1241 | power_state); | ||
1242 | } | ||
1243 | |||
1244 | if (power_state == AC_PWRST_D0) | ||
1245 | msleep(10); | ||
1246 | } | ||
1247 | |||
1248 | |||
1198 | /** | 1249 | /** |
1199 | * snd_hda_build_controls - build mixer controls | 1250 | * snd_hda_build_controls - build mixer controls |
1200 | * @bus: the BUS | 1251 | * @bus: the BUS |
@@ -1222,6 +1273,9 @@ int snd_hda_build_controls(struct hda_bus *bus) | |||
1222 | list_for_each(p, &bus->codec_list) { | 1273 | list_for_each(p, &bus->codec_list) { |
1223 | struct hda_codec *codec = list_entry(p, struct hda_codec, list); | 1274 | struct hda_codec *codec = list_entry(p, struct hda_codec, list); |
1224 | int err; | 1275 | int err; |
1276 | hda_set_power_state(codec, | ||
1277 | codec->afg ? codec->afg : codec->mfg, | ||
1278 | AC_PWRST_D0); | ||
1225 | if (! codec->patch_ops.init) | 1279 | if (! codec->patch_ops.init) |
1226 | continue; | 1280 | continue; |
1227 | err = codec->patch_ops.init(codec); | 1281 | err = codec->patch_ops.init(codec); |
@@ -1340,7 +1394,7 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
1340 | 1394 | ||
1341 | val = 0; | 1395 | val = 0; |
1342 | if (nid != codec->afg && | 1396 | if (nid != codec->afg && |
1343 | snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP) & AC_WCAP_FORMAT_OVRD) { | 1397 | (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) { |
1344 | val = snd_hda_param_read(codec, nid, AC_PAR_PCM); | 1398 | val = snd_hda_param_read(codec, nid, AC_PAR_PCM); |
1345 | if (val == -1) | 1399 | if (val == -1) |
1346 | return -EIO; | 1400 | return -EIO; |
@@ -1362,7 +1416,7 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | |||
1362 | unsigned int bps; | 1416 | unsigned int bps; |
1363 | unsigned int wcaps; | 1417 | unsigned int wcaps; |
1364 | 1418 | ||
1365 | wcaps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); | 1419 | wcaps = get_wcaps(codec, nid); |
1366 | streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); | 1420 | streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); |
1367 | if (streams == -1) | 1421 | if (streams == -1) |
1368 | return -EIO; | 1422 | return -EIO; |
@@ -1432,7 +1486,7 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, | |||
1432 | unsigned int val = 0, rate, stream; | 1486 | unsigned int val = 0, rate, stream; |
1433 | 1487 | ||
1434 | if (nid != codec->afg && | 1488 | if (nid != codec->afg && |
1435 | snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP) & AC_WCAP_FORMAT_OVRD) { | 1489 | (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD)) { |
1436 | val = snd_hda_param_read(codec, nid, AC_PAR_PCM); | 1490 | val = snd_hda_param_read(codec, nid, AC_PAR_PCM); |
1437 | if (val == -1) | 1491 | if (val == -1) |
1438 | return 0; | 1492 | return 0; |
@@ -1658,9 +1712,21 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) | |||
1658 | int err; | 1712 | int err; |
1659 | 1713 | ||
1660 | for (; knew->name; knew++) { | 1714 | for (; knew->name; knew++) { |
1661 | err = snd_ctl_add(codec->bus->card, snd_ctl_new1(knew, codec)); | 1715 | struct snd_kcontrol *kctl; |
1662 | if (err < 0) | 1716 | kctl = snd_ctl_new1(knew, codec); |
1663 | return err; | 1717 | if (! kctl) |
1718 | return -ENOMEM; | ||
1719 | err = snd_ctl_add(codec->bus->card, kctl); | ||
1720 | if (err < 0) { | ||
1721 | if (! codec->addr) | ||
1722 | return err; | ||
1723 | kctl = snd_ctl_new1(knew, codec); | ||
1724 | if (! kctl) | ||
1725 | return -ENOMEM; | ||
1726 | kctl->id.device = codec->addr; | ||
1727 | if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) | ||
1728 | return err; | ||
1729 | } | ||
1664 | } | 1730 | } |
1665 | return 0; | 1731 | return 0; |
1666 | } | 1732 | } |
@@ -1874,8 +1940,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c | |||
1874 | 1940 | ||
1875 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); | 1941 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); |
1876 | for (nid = nid_start; nid < nodes + nid_start; nid++) { | 1942 | for (nid = nid_start; nid < nodes + nid_start; nid++) { |
1877 | unsigned int wid_caps = snd_hda_param_read(codec, nid, | 1943 | unsigned int wid_caps = get_wcaps(codec, nid); |
1878 | AC_PAR_AUDIO_WIDGET_CAP); | ||
1879 | unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 1944 | unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; |
1880 | unsigned int def_conf; | 1945 | unsigned int def_conf; |
1881 | short assoc, loc; | 1946 | short assoc, loc; |
@@ -1993,6 +2058,9 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) | |||
1993 | struct hda_codec *codec = list_entry(p, struct hda_codec, list); | 2058 | struct hda_codec *codec = list_entry(p, struct hda_codec, list); |
1994 | if (codec->patch_ops.suspend) | 2059 | if (codec->patch_ops.suspend) |
1995 | codec->patch_ops.suspend(codec, state); | 2060 | codec->patch_ops.suspend(codec, state); |
2061 | hda_set_power_state(codec, | ||
2062 | codec->afg ? codec->afg : codec->mfg, | ||
2063 | AC_PWRST_D3); | ||
1996 | } | 2064 | } |
1997 | return 0; | 2065 | return 0; |
1998 | } | 2066 | } |
@@ -2010,6 +2078,9 @@ int snd_hda_resume(struct hda_bus *bus) | |||
2010 | 2078 | ||
2011 | list_for_each(p, &bus->codec_list) { | 2079 | list_for_each(p, &bus->codec_list) { |
2012 | struct hda_codec *codec = list_entry(p, struct hda_codec, list); | 2080 | struct hda_codec *codec = list_entry(p, struct hda_codec, list); |
2081 | hda_set_power_state(codec, | ||
2082 | codec->afg ? codec->afg : codec->mfg, | ||
2083 | AC_PWRST_D0); | ||
2013 | if (codec->patch_ops.resume) | 2084 | if (codec->patch_ops.resume) |
2014 | codec->patch_ops.resume(codec); | 2085 | codec->patch_ops.resume(codec); |
2015 | } | 2086 | } |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 0b5c36788898..63e26c7a2b7a 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -214,6 +214,12 @@ enum { | |||
214 | #define AC_PWRST_D2SUP (1<<2) | 214 | #define AC_PWRST_D2SUP (1<<2) |
215 | #define AC_PWRST_D3SUP (1<<3) | 215 | #define AC_PWRST_D3SUP (1<<3) |
216 | 216 | ||
217 | /* Power state values */ | ||
218 | #define AC_PWRST_D0 0x00 | ||
219 | #define AC_PWRST_D1 0x01 | ||
220 | #define AC_PWRST_D2 0x02 | ||
221 | #define AC_PWRST_D3 0x03 | ||
222 | |||
217 | /* Processing capabilies */ | 223 | /* Processing capabilies */ |
218 | #define AC_PCAP_BENIGN (1<<0) | 224 | #define AC_PCAP_BENIGN (1<<0) |
219 | #define AC_PCAP_NUM_COEF (0xff<<8) | 225 | #define AC_PCAP_NUM_COEF (0xff<<8) |
@@ -376,7 +382,7 @@ enum { | |||
376 | }; | 382 | }; |
377 | 383 | ||
378 | /* max. connections to a widget */ | 384 | /* max. connections to a widget */ |
379 | #define HDA_MAX_CONNECTIONS 16 | 385 | #define HDA_MAX_CONNECTIONS 32 |
380 | 386 | ||
381 | /* max. codec address */ | 387 | /* max. codec address */ |
382 | #define HDA_MAX_CODEC_ADDRESS 0x0f | 388 | #define HDA_MAX_CODEC_ADDRESS 0x0f |
@@ -542,6 +548,11 @@ struct hda_codec { | |||
542 | /* codec specific info */ | 548 | /* codec specific info */ |
543 | void *spec; | 549 | void *spec; |
544 | 550 | ||
551 | /* widget capabilities cache */ | ||
552 | unsigned int num_nodes; | ||
553 | hda_nid_t start_nid; | ||
554 | u32 *wcaps; | ||
555 | |||
545 | /* hash for amp access */ | 556 | /* hash for amp access */ |
546 | u16 amp_hash[32]; | 557 | u16 amp_hash[32]; |
547 | int num_amp_entries; | 558 | int num_amp_entries; |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 502290424c67..ded32359b654 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -87,7 +87,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); | |||
87 | /* | 87 | /* |
88 | * input MUX helper | 88 | * input MUX helper |
89 | */ | 89 | */ |
90 | #define HDA_MAX_NUM_INPUTS 8 | 90 | #define HDA_MAX_NUM_INPUTS 16 |
91 | struct hda_input_mux_item { | 91 | struct hda_input_mux_item { |
92 | const char *label; | 92 | const char *label; |
93 | unsigned int index; | 93 | unsigned int index; |
@@ -243,4 +243,16 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c | |||
243 | #define PIN_HP 0xc0 | 243 | #define PIN_HP 0xc0 |
244 | #define PIN_HP_AMP 0x80 | 244 | #define PIN_HP_AMP 0x80 |
245 | 245 | ||
246 | /* | ||
247 | * get widget capabilities | ||
248 | */ | ||
249 | static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid) | ||
250 | { | ||
251 | if (nid < codec->start_nid || | ||
252 | nid >= codec->start_nid + codec->num_nodes) | ||
253 | return snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); | ||
254 | return codec->wcaps[nid - codec->start_nid]; | ||
255 | } | ||
256 | |||
257 | |||
246 | #endif /* __SOUND_HDA_LOCAL_H */ | 258 | #endif /* __SOUND_HDA_LOCAL_H */ |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 62e6993056e6..77c5f95ea55b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -2091,8 +2091,7 @@ static int patch_alc880(struct hda_codec *codec) | |||
2091 | 2091 | ||
2092 | if (! spec->adc_nids && spec->input_mux) { | 2092 | if (! spec->adc_nids && spec->input_mux) { |
2093 | /* check whether NID 0x07 is valid */ | 2093 | /* check whether NID 0x07 is valid */ |
2094 | unsigned int wcap = snd_hda_param_read(codec, alc880_adc_nids[0], | 2094 | unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); |
2095 | AC_PAR_AUDIO_WIDGET_CAP); | ||
2096 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ | 2095 | wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ |
2097 | if (wcap != AC_WID_AUD_IN) { | 2096 | if (wcap != AC_WID_AUD_IN) { |
2098 | spec->adc_nids = alc880_adc_nids_alt; | 2097 | spec->adc_nids = alc880_adc_nids_alt; |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index d8d68f5b6131..c8c539cb4a8f 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -624,7 +624,7 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, struct auto_pin | |||
624 | if (! pin) | 624 | if (! pin) |
625 | return 0; | 625 | return 0; |
626 | 626 | ||
627 | wid_caps = snd_hda_param_read(codec, pin, AC_PAR_AUDIO_WIDGET_CAP); | 627 | wid_caps = get_wcaps(codec, pin); |
628 | if (wid_caps & AC_WCAP_UNSOL_CAP) | 628 | if (wid_caps & AC_WCAP_UNSOL_CAP) |
629 | /* Enable unsolicited responses on the HP widget */ | 629 | /* Enable unsolicited responses on the HP widget */ |
630 | snd_hda_codec_write(codec, pin, 0, | 630 | snd_hda_codec_write(codec, pin, 0, |
@@ -786,33 +786,10 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) | |||
786 | return 1; | 786 | return 1; |
787 | } | 787 | } |
788 | 788 | ||
789 | static int stac92xx_init_pstate(struct hda_codec *codec) | ||
790 | { | ||
791 | hda_nid_t nid, nid_start; | ||
792 | int nodes; | ||
793 | |||
794 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_POWER_STATE, 0x00); | ||
795 | |||
796 | nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); | ||
797 | for (nid = nid_start; nid < nodes + nid_start; nid++) { | ||
798 | unsigned int wid_caps = snd_hda_param_read(codec, nid, | ||
799 | AC_PAR_AUDIO_WIDGET_CAP); | ||
800 | if (wid_caps & AC_WCAP_POWER) | ||
801 | snd_hda_codec_write(codec, nid, 0, | ||
802 | AC_VERB_SET_POWER_STATE, 0x00); | ||
803 | } | ||
804 | |||
805 | mdelay(100); | ||
806 | |||
807 | return 0; | ||
808 | } | ||
809 | |||
810 | static int stac92xx_init(struct hda_codec *codec) | 789 | static int stac92xx_init(struct hda_codec *codec) |
811 | { | 790 | { |
812 | struct sigmatel_spec *spec = codec->spec; | 791 | struct sigmatel_spec *spec = codec->spec; |
813 | 792 | ||
814 | stac92xx_init_pstate(codec); | ||
815 | |||
816 | snd_hda_sequence_write(codec, spec->init); | 793 | snd_hda_sequence_write(codec, spec->init); |
817 | 794 | ||
818 | stac92xx_auto_init_multi_out(codec); | 795 | stac92xx_auto_init_multi_out(codec); |