At Mon, 02 Feb 2004 19:42:37 +0000, James Courtier-Dutton wrote: > > Once thing I have noticed, is that with the alc650, we used to have VRA > (alsa 0.9.8), but the 1.0.2 intel8x0 driver ignores the VRA and fixes > itself at 48000.
yes, the detection of sample rate range seems broken for some codecs. it was completely rewritten using the generic ac97_pcm.c. could you check the debug messages with the attached patch? Takashi
Index: alsa-kernel/pci/ac97/ac97_pcm.c =================================================================== RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/pci/ac97/ac97_pcm.c,v retrieving revision 1.10 diff -u -r1.10 ac97_pcm.c --- alsa-kernel/pci/ac97/ac97_pcm.c 2 Jan 2004 13:39:33 -0000 1.10 +++ alsa-kernel/pci/ac97/ac97_pcm.c 4 Feb 2004 19:32:50 -0000 @@ -284,6 +284,7 @@ if (ac97_is_rev22(ac97)) { /* Note: it's simply emulation of AMAP behaviour */ u16 es; + printk(KERN_DEBUG "get_pslots: rev22 amap emu\n"); es = ac97->regs[AC97_EXTENDED_STATUS] &= ~AC97_EI_DACS_SLOT_MASK; switch (ac97->addr) { case 1: @@ -292,6 +293,7 @@ } snd_ac97_write_cache(ac97, AC97_EXTENDED_STATUS, es); } + printk(KERN_DEBUG "get_pslots: AMAP: addr=%d, scaps=0x%x, ext_id=0x%x\n", ac97->addr, ac97->scaps, ac97->ext_id); switch (ac97->addr) { case 0: slots |= (1<<AC97_SLOT_PCM_LEFT)|(1<<AC97_SLOT_PCM_RIGHT); @@ -332,6 +334,7 @@ return slots; } else { unsigned short slots; + printk(KERN_DEBUG "get_pslots: others: addr=%d, scaps=0x%x, ext_id=0x%x\n", ac97->addr, ac97->scaps, ac97->ext_id); slots = (1<<AC97_SLOT_PCM_LEFT)|(1<<AC97_SLOT_PCM_RIGHT); if (ac97->scaps & AC97_SCAP_SURROUND_DAC) slots |= (1<<AC97_SLOT_PCM_SLEFT)|(1<<AC97_SLOT_PCM_SRIGHT); @@ -420,16 +423,19 @@ continue; avail_slots[0][i] = get_pslots(codec, &rate_table[0][i], &spdif_slots[i]); avail_slots[1][i] = get_cslots(codec); + printk(KERN_DEBUG "checking codec %d, slots = 0x%x / 0x%x\n", i, avail_slots[0][i], avail_slots[1][i]); if (!(codec->scaps & AC97_SCAP_INDEP_SDIN)) { for (j = 0; j < i; j++) { if (bus->codec[j]) avail_slots[1][i] &= ~avail_slots[1][j]; } + printk(KERN_DEBUG "-> capture slots = 0x%x\n", avail_slots[1][i]); } } /* FIXME: add double rate allocation */ /* first step - exclusive devices */ for (i = 0; i < pcms_count; i++) { + printk(KERN_DEBUG "probing pcm %d\n", i); pcm = &pcms[i]; rpcm = &rpcms[i]; /* low-level driver thinks that it's more clever */ @@ -452,22 +458,27 @@ tmp = spdif_slots[j]; else tmp = avail_slots[pcm->stream][j]; + printk(KERN_DEBUG ".. probing codec %d, slots = 0x%x, tmp = 0x%x\n", j, slots, tmp); if (pcm->exclusive) { /* exclusive access */ tmp &= slots; + printk(KERN_DEBUG ".. exclusive tmp = 0x%x\n", tmp); for (k = 0; k < i; k++) { if (rpcm->stream == rpcms[k].stream) tmp &= ~rpcms[k].r[0].rslots[j]; } + printk(KERN_DEBUG "..... tmp = 0x%x\n", tmp); } else { /* non-exclusive access */ tmp &= pcm->r[0].slots; + printk(KERN_DEBUG ".. non-exclusive tmp = 0x%x\n", tmp); } if (tmp) { rpcm->r[0].rslots[j] = tmp; rpcm->r[0].codec[j] = bus->codec[j]; rpcm->r[0].rate_table[j] = rate_table[pcm->stream][j]; rates = get_rates(rpcm, j, tmp, 0); + printk(KERN_DEBUG ".. rslots = 0x%x, rate_table = %d, rates = 0x%x\n", tmp, rpcm->r[0].rate_table[j], rates); if (pcm->exclusive) avail_slots[pcm->stream][j] &= ~tmp; } @@ -475,6 +486,7 @@ rpcm->r[0].slots |= tmp; rpcm->rates &= rates; } + printk(KERN_DEBUG "--> slots = 0x%x, rates = 0x%x\n", rpcm->r[0].slots, rpcm->rates); if (rpcm->rates == ~0) rpcm->rates = 0; /* not used */ } @@ -501,6 +513,7 @@ unsigned char reg; int err = 0; + printk(KERN_DEBUG "ac97_pcm_open: rate = %d, cfg = %d, slots = 0x%x\n", rate, cfg, slots); if (rate > 48000) /* FIXME: add support for double rate */ return -EINVAL; bus = pcm->bus; @@ -549,7 +562,7 @@ } if (reg_ok & (1 << (reg - AC97_PCM_FRONT_DAC_RATE))) continue; - //printk(KERN_DEBUG "setting ac97 reg 0x%x to rate %d\n", reg, rate); + printk(KERN_DEBUG "setting ac97 reg 0x%x to rate %d\n", reg, rate); err = snd_ac97_set_rate(pcm->r[r].codec[cidx], reg, rate); if (err < 0) snd_printk(KERN_ERR "error in snd_ac97_set_rate: cidx=%d, reg=0x%x, rate=%d, err=%d\n", cidx, reg, rate, err);