[prev in list] [next in list] [prev in thread] [next in thread]
List: netbsd-bugs
Subject: kern/26457: ac97 is not ready after suspend/resume (fix included, should be considered for 2.0)
From: Joachim.Thiemann () Mail ! McGill ! CA
Date: 2004-07-28 1:49:00
Message-ID: 20040728014900.99A9D11153 () narn ! netbsd ! org
[Download RAW message or body]
> Number: 26457
> Category: kern
> Synopsis: ac97 is not ready after suspend/resume (fix included, should be \
> considered for 2.0)
> Confidential: no
> Severity: non-critical
> Priority: medium
> Responsible: kern-bug-people
> State: open
> Class: sw-bug
> Submitter-Id: net
> Arrival-Date: Wed Jul 28 04:14:00 UTC 2004
> Closed-Date:
> Last-Modified:
> Originator: Joachim Thiemann
> Release: 2.0_BETA
> Organization:
> Environment:
NetBSD codaget3002 2.0_BETA NetBSD 2.0_BETA (IBMT30) #28: Thu Jul 15 21:57:25 EDT \
2004 thiemann@codaget3002:/home/thiemann/NetBSD/sys/arch/i386/compile/IBMT30 i386
from dmesg:
auich0 at pci0 dev 31 function 5: i82801CA (ICH3) AC-97 Audio
auich0: interrupting at irq 5
auich0: ac97: Analog Devices AD1881A codec; headphone, Analog Devices Phat Stereo
auich0: ac97: ext id 1<VRA>
auich0: measured ac97 link rate at 47277 Hz, will use 48000 Hz
> Description:
After a suspend/resume cycle of a laptop, the ac97 takes some time
to power up fully. If registers are modified before that, it
the changes are ignored. In particular, the ac97_restore_shadow
function is ignored, and the pre-suspend mixer values are lost.
Also, the chip may get stuck in the 48000 sample rate.
> How-To-Repeat:
Have a sound file sampled at low rate (eg. 8000 or 16000 Hz)
audioplay soundfile.wav
(suspend)
(resume)
audioplay soundfile.wav
mixerctl -w outputs.master.mute=off
mixerctl -w inputs.dac.mute=off
audioplay soundfile.wav
> Fix:
I have patched ac97.c to 1) wait until the power register claims that all subsystems \
are powered up, and 2) try modifying the master volume, until the write actually \
suceeds.
RCS file: /cvsroot/src/sys/dev/ic/ac97.c,v
retrieving revision 1.52
diff -c -r1.52 ac97.c
*** ac97.c 24 Nov 2003 16:05:10 -0000 1.52
--- ac97.c 28 Jul 2004 04:00:46 -0000
***************
*** 702,712 ****
struct ac97_softc *as;
const struct ac97_source_info *si;
int idx;
as = (struct ac97_softc *) self;
for (idx = 0; idx < SOURCE_INFO_SIZE; idx++) {
si = &source_info[idx];
! ac97_write(as, si->reg, as->shadow_reg[si->reg >> 1]);
}
if (as->ext_id & (AC97_EXT_AUDIO_VRA | AC97_EXT_AUDIO_DRA
--- 702,740 ----
struct ac97_softc *as;
const struct ac97_source_info *si;
int idx;
+ u_int16_t val;
as = (struct ac97_softc *) self;
+
+ /* make sure chip is fully operational */
+ for (idx = 500000; idx >= 0; idx--) {
+ ac97_read(as, AC97_REG_POWER, &val);
+ if ((val & AC97_POWER_REF) &&
+ (val & AC97_POWER_ANL) &&
+ (val & AC97_POWER_DAC) &&
+ (val & AC97_POWER_ADC)) break;
+ DELAY(1);
+ }
+
+ if (idx <= 0)
+ printf( "ac97 timeout on restore\n" );
+
+ /* actually try changing a value! */
+ for (idx = 500000; idx >= 0; idx--) {
+ as->host_if->write(as->host_if->arg, AC97_REG_MASTER_VOLUME, 0x1010);
+ ac97_read(as, AC97_REG_MASTER_VOLUME, &val);
+ if (val == 0x1010) break;
+ DELAY(1);
+ }
+
+ if (idx <= 0)
+ printf( "ac97 timeout on ch reg\n" );
+
for (idx = 0; idx < SOURCE_INFO_SIZE; idx++) {
si = &source_info[idx];
! /* don't "restore" to the reset reg! */
! if (si->reg)
! ac97_write(as, si->reg, as->shadow_reg[si->reg >> 1]);
}
if (as->ext_id & (AC97_EXT_AUDIO_VRA | AC97_EXT_AUDIO_DRA
> Release-Note:
> Audit-Trail:
> Unformatted:
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic