Re-work ac97 initialization to match cold reset described in AC97r.23
and be prepared to wait much longer for codec to become ready. Credit to Hugo D. Valentim <hvalentim@gmx.net> for reporting the problem, providing useful pointers, and repeated diff testing.
This commit is contained in:
parent
8f832fd0ba
commit
abe88fc972
@ -462,7 +462,7 @@ via_attach(device_t dev)
|
|||||||
{
|
{
|
||||||
struct via_info *via = 0;
|
struct via_info *via = 0;
|
||||||
char status[SND_STATUSLEN];
|
char status[SND_STATUSLEN];
|
||||||
u_int32_t data;
|
u_int32_t data, cnt;
|
||||||
|
|
||||||
if ((via = malloc(sizeof *via, M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
|
if ((via = malloc(sizeof *via, M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
|
||||||
device_printf(dev, "cannot allocate softc\n");
|
device_printf(dev, "cannot allocate softc\n");
|
||||||
@ -476,18 +476,25 @@ via_attach(device_t dev)
|
|||||||
data = pci_read_config(dev, PCIR_COMMAND, 2);
|
data = pci_read_config(dev, PCIR_COMMAND, 2);
|
||||||
|
|
||||||
/* Wake up and reset AC97 if necessary */
|
/* Wake up and reset AC97 if necessary */
|
||||||
if (!(pci_read_config(dev, VIA_AC97STATUS, 1) & VIA_AC97STATUS_RDY)) {
|
data = pci_read_config(dev, VIA_AC97STATUS, 1);
|
||||||
pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_EN | VIA_ACLINK_NRST | VIA_ACLINK_SYNC, 1);
|
if ((data & VIA_AC97STATUS_RDY) == 0) {
|
||||||
DELAY(1000);
|
/* Cold reset per ac97r2.3 spec (page 95) */
|
||||||
pci_write_config(dev, VIA_ACLINKCTRL, 0, 1);
|
pci_write_config(dev, VIA_ACLINKCTRL, 0, 1); /* Assert low */
|
||||||
DELAY(1000);
|
DELAY(100); /* Wait T_rst_low */
|
||||||
pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_DESIRED, 1);
|
pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_NRST, 1); /* Assert high */
|
||||||
DELAY(1000);
|
DELAY(1); /* Wait T_rst2clk */
|
||||||
}
|
pci_write_config(dev, VIA_ACLINKCTRL, 0, 1); /* Assert low */
|
||||||
|
|
||||||
if (pci_read_config(dev, VIA_ACLINKCTRL, 1) != VIA_ACLINK_DESIRED) {
|
/* Power everything up */
|
||||||
pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_DESIRED, 1);
|
pci_write_config(dev, VIA_ACLINKCTRL, VIA_ACLINK_DESIRED, 1);
|
||||||
DELAY(1000);
|
|
||||||
|
/* 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;
|
via->regid = PCIR_MAPS;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user