diff options
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/dev/ic/ac97.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/sys/dev/ic/ac97.c b/sys/dev/ic/ac97.c index 55ff1833d01..4dd1fca687f 100644 --- a/sys/dev/ic/ac97.c +++ b/sys/dev/ic/ac97.c @@ -1,4 +1,4 @@ -/* $NetBSD: ac97.c,v 1.58 2004/08/08 10:41:57 kent Exp $ */ +/* $NetBSD: ac97.c,v 1.59 2004/08/20 14:36:13 kent Exp $ */ /* $OpenBSD: ac97.c,v 1.8 2000/07/19 09:01:35 csapuntz Exp $ */ /* @@ -63,7 +63,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ac97.c,v 1.58 2004/08/08 10:41:57 kent Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ac97.c,v 1.59 2004/08/20 14:36:13 kent Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -727,11 +727,26 @@ ac97_restore_shadow(struct ac97_codec_if *self) struct ac97_softc *as; const struct ac97_source_info *si; int idx; + uint16_t val; as = (struct ac97_softc *) self; + + /* make sure chip is fully operational */ +#define AC97_POWER_ALL (AC97_POWER_REF | AC97_POWER_ANL | AC97_POWER_DAC \ + | AC97_POWER_ADC) + for (idx = 500000; idx >= 0; idx--) { + ac97_read(as, AC97_REG_POWER, &val); + if ((val & AC97_POWER_ALL) == AC97_POWER_ALL) + break; + DELAY(1); + } +#undef AC97_POWER_ALL + for (idx = 0; idx < SOURCE_INFO_SIZE; idx++) { si = &source_info[idx]; - ac97_write(as, si->reg, as->shadow_reg[si->reg >> 1]); + /* don't "restore" to the reset reg! */ + if (si->reg != AC97_REG_RESET) + ac97_write(as, si->reg, as->shadow_reg[si->reg >> 1]); } if (as->ext_id & (AC97_EXT_AUDIO_VRA | AC97_EXT_AUDIO_DRA @@ -880,9 +895,10 @@ ac97_attach(struct ac97_host_if *host_if) struct ac97_softc *as; struct device *sc_dev; int error, i, j; - u_int32_t id; - u_int16_t id1, id2; - u_int16_t extstat, rate; + uint32_t id; + uint16_t id1, id2; + uint16_t extstat, rate; + uint16_t val; mixer_ctrl_t ctl; void (*initfunc)(struct ac97_softc *); #define FLAGBUFLEN 140 @@ -911,6 +927,16 @@ ac97_attach(struct ac97_host_if *host_if) if (host_if->flags) as->host_flags = host_if->flags(host_if->arg); +#define AC97_POWER_ALL (AC97_POWER_REF | AC97_POWER_ANL | AC97_POWER_DAC \ + | AC97_POWER_ADC) + for (i = 500000; i >= 0; i--) { + ac97_read(as, AC97_REG_POWER, &val); + if ((val & AC97_POWER_ALL) == AC97_POWER_ALL) + break; + DELAY(1); + } +#undef AC97_POWER_ALL + ac97_setup_defaults(as); ac97_read(as, AC97_REG_RESET, &as->caps); ac97_read(as, AC97_REG_VENDOR_ID1, &id1); @@ -1019,9 +1045,7 @@ ac97_attach(struct ac97_host_if *host_if) ac97_setup_source_info(as); - DELAY(900 * 1000); memset(&ctl, 0, sizeof(ctl)); - /* disable mutes */ for (i = 0; i < 11; i++) { static struct { |
