diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-28 08:41:58 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-28 08:41:58 -0700 |
commit | 7b70888a192eff457c2ca0a4ffa04815f5e19734 (patch) | |
tree | 8c75d6908b1e83b750b50e7a26da867926e0f5cd /sound/pci/ac97/ac97_codec.c | |
parent | cd85c8b4457a52d3545fdb9532082b2c1ebd5f21 (diff) | |
parent | 0a97af41b0e77f834acc0870155de616a373e899 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
Diffstat (limited to 'sound/pci/ac97/ac97_codec.c')
-rw-r--r-- | sound/pci/ac97/ac97_codec.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index a4b72cd2eea0..6983eea226da 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -367,6 +367,7 @@ int snd_ac97_update(ac97_t *ac97, unsigned short reg, unsigned short value) ac97->regs[reg] = value; ac97->bus->ops->write(ac97, reg, value); } + set_bit(reg, ac97->reg_accessed); up(&ac97->reg_mutex); return change; } @@ -410,6 +411,7 @@ int snd_ac97_update_bits_nolock(ac97_t *ac97, unsigned short reg, ac97->regs[reg] = new; ac97->bus->ops->write(ac97, reg, new); } + set_bit(reg, ac97->reg_accessed); return change; } @@ -1076,6 +1078,11 @@ static void check_volume_resolution(ac97_t *ac97, int reg, unsigned char *lo_max for (i = 0 ; i < ARRAY_SIZE(cbit); i++) { unsigned short val; snd_ac97_write(ac97, reg, 0x8080 | cbit[i] | (cbit[i] << 8)); + /* Do the read twice due to buffers on some ac97 codecs. + * e.g. The STAC9704 returns exactly what you wrote the the register + * if you read it immediately. This causes the detect routine to fail. + */ + val = snd_ac97_read(ac97, reg); val = snd_ac97_read(ac97, reg); if (! *lo_max && (val & 0x7f) == cbit[i]) *lo_max = max[i]; @@ -2224,7 +2231,7 @@ void snd_ac97_restore_iec958(ac97_t *ac97) */ void snd_ac97_resume(ac97_t *ac97) { - int i; + unsigned long end_time; if (ac97->bus->ops->reset) { ac97->bus->ops->reset(ac97); @@ -2242,26 +2249,26 @@ void snd_ac97_resume(ac97_t *ac97) snd_ac97_write(ac97, AC97_POWERDOWN, ac97->regs[AC97_POWERDOWN]); if (ac97_is_audio(ac97)) { ac97->bus->ops->write(ac97, AC97_MASTER, 0x8101); - for (i = HZ/10; i >= 0; i--) { + end_time = jiffies + msecs_to_jiffies(100); + do { if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101) break; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); - } + } while (time_after_eq(end_time, jiffies)); /* FIXME: extra delay */ ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); - if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(HZ/4); - } + if (snd_ac97_read(ac97, AC97_MASTER) != 0x8000) + msleep(250); } else { - for (i = HZ/10; i >= 0; i--) { + end_time = jiffies + msecs_to_jiffies(100); + do { unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID); if (val != 0xffff && (val & 1) != 0) break; set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout(1); - } + } while (time_after_eq(end_time, jiffies)); } __reset_ready: |