diff options
author | orion <orion@FreeBSD.org> | 2003-03-28 16:33:15 +0000 |
---|---|---|
committer | orion <orion@FreeBSD.org> | 2003-03-28 16:33:15 +0000 |
commit | 7f82ad918495ef3ec718932a65ab651327491593 (patch) | |
tree | ae871bd8bec3f80df47ca7511e9b213b0e84a4ae /sys | |
parent | d0ac4347903603c9730f996164d5eea70f08cc88 (diff) | |
download | FreeBSD-src-7f82ad918495ef3ec718932a65ab651327491593.zip FreeBSD-src-7f82ad918495ef3ec718932a65ab651327491593.tar.gz |
Perform warm reset if codec reports ready on attach.
Move AC97 link control power up poke so it is always performed on attach.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/sound/pci/via82c686.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/sys/dev/sound/pci/via82c686.c b/sys/dev/sound/pci/via82c686.c index 262ac5a..2e958ac 100644 --- a/sys/dev/sound/pci/via82c686.c +++ b/sys/dev/sound/pci/via82c686.c @@ -477,24 +477,33 @@ via_attach(device_t dev) /* Wake up and reset AC97 if necessary */ data = pci_read_config(dev, VIA_AC97STATUS, 1); + if ((data & VIA_AC97STATUS_RDY) == 0) { /* Cold reset per ac97r2.3 spec (page 95) */ - pci_write_config(dev, VIA_ACLINKCTRL, 0, 1); /* Assert low */ - DELAY(100); /* Wait T_rst_low */ - pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_NRST, 1); /* Assert high */ - DELAY(1); /* Wait T_rst2clk */ - pci_write_config(dev, VIA_ACLINKCTRL, 0, 1); /* Assert low */ - - /* Power everything up */ - pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_DESIRED, 1); - - /* Wait for codec to become ready (largest reported delay here 310ms) */ - for (cnt = 0; cnt < 2000; cnt++) { - data = pci_read_config(dev, VIA_AC97STATUS, 1); - if (data & VIA_AC97STATUS_RDY) - break; - DELAY(5000); - } + pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN, 1); /* Assert low */ + DELAY(100); /* Wait T_rst_low */ + pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN | VIA_ACLINK_NRST, 1); /* Assert high */ + DELAY(5); /* Wait T_rst2clk */ + pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN, 1); /* Assert low */ + } else { + /* Warm reset */ + pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN, 1); /* Force no sync */ + DELAY(100); + pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN | VIA_ACLINK_SYNC, 1); /* Sync */ + DELAY(5); /* Wait T_sync_high */ + pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN, 1); /* Force no sync */ + DELAY(5); /* Wait T_sync2clk */ + } + + /* Power everything up */ + pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_DESIRED, 1); + + /* Wait for codec to become ready (largest reported delay here 310ms) */ + for (cnt = 0; cnt < 2000; cnt++) { + data = pci_read_config(dev, VIA_AC97STATUS, 1); + if (data & VIA_AC97STATUS_RDY) + break; + DELAY(5000); } via->regid = PCIR_MAPS; |