At Thu, 7 Jun 2007 01:01:54 -0500 (CDT), acallan.alsa@ugnet.org wrote:
On Wed, 6 Jun 2007, Takashi Iwai wrote:
At Wed, 6 Jun 2007 01:07:15 -0500 (CDT), acallan.alsa@ugnet.org wrote:
cat /proc/asound/card0/codec#1 works just fine, and sound still works fine even after that. Looking at the function print_codec_info() (hda_proc.c), there is already the check: if (! codec->afg) return; after the vendor, subsystem, and revision are retrieved but before the pcm, amp caps, and node information are retrieved.
Oh silly me.
I guess the following patch works alone. Could you test it?
Takashi
I had to also add in the workarounds for the power states as in the following patch.
Did you try my latest patch? It sets the power state of only the FG node, and doesn't touch child nodes any more for modem FG. You patch will skip the power state completely for modem FG.
Takashi
Andrew
diff -r 8bc69e73a655 pci/hda/hda_codec.c --- a/pci/hda/hda_codec.c Wed Jun 06 14:48:52 2007 +0200 +++ b/pci/hda/hda_codec.c Wed Jun 06 23:35:39 2007 -0500 @@ -562,7 +562,7 @@ int __devinit snd_hda_codec_new(struct h return -ENODEV; }
- if (read_widget_caps(codec, codec->afg ? codec->afg : codec->mfg) < 0) {
- if (codec->afg && read_widget_caps(codec, codec->afg) < 0) { snd_printk(KERN_ERR "hda_codec: cannot malloc\n"); snd_hda_codec_free(codec); return -ENOMEM;
@@ -1389,9 +1389,8 @@ int __devinit snd_hda_build_controls(str /* initialize */ list_for_each_entry(codec, &bus->codec_list, list) { int err;
hda_set_power_state(codec,
codec->afg ? codec->afg : codec->mfg,
AC_PWRST_D0);
if (codec->afg)
if (!codec->patch_ops.init) continue; err = codec->patch_ops.init(codec);hda_set_power_state(codec, codec->afg, AC_PWRST_D0);
@@ -2375,9 +2374,8 @@ int snd_hda_suspend(struct hda_bus *bus, list_for_each_entry(codec, &bus->codec_list, list) { if (codec->patch_ops.suspend) codec->patch_ops.suspend(codec, state);
hda_set_power_state(codec,
codec->afg ? codec->afg : codec->mfg,
AC_PWRST_D3);
if (codec->afg)
} return 0;hda_set_power_state(codec, codec->afg, AC_PWRST_D3);
} @@ -2394,9 +2392,8 @@ int snd_hda_resume(struct hda_bus *bus) struct hda_codec *codec;
list_for_each_entry(codec, &bus->codec_list, list) {
hda_set_power_state(codec,
codec->afg ? codec->afg : codec->mfg,
AC_PWRST_D0);
if (codec->afg)
if (codec->patch_ops.resume) codec->patch_ops.resume(codec); }hda_set_power_state(codec, codec->afg, AC_PWRST_D0);
diff -r 8bc69e73a655 pci/hda/hda_local.h --- a/pci/hda/hda_local.h Wed Jun 06 14:48:52 2007 +0200 +++ b/pci/hda/hda_local.h Wed Jun 06 23:32:46 2007 -0500 @@ -274,7 +274,7 @@ static inline u32 get_wcaps(struct hda_c if (nid < codec->start_nid || nid >= codec->start_nid + codec->num_nodes) return snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
- return codec->wcaps[nid - codec->start_nid];
- return codec->wcaps ? codec->wcaps[nid - codec->start_nid] : 0;
}
int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,