Index: ich.c =================================================================== RCS file: /home/ncvs/src/sys/dev/sound/pci/ich.c,v retrieving revision 1.3.2.4 diff -r1.3.2.4 ich.c 53,54c53,54 < u_int32_t num, run; < u_int32_t blksz, blkcnt; --- > u_int32_t num:8, run:1, run_save:1; > u_int32_t blksz, blkcnt, spd; 295,297c295,296 < r = speed * 48000 / sc->ac97rate; < return ac97_setrate(sc->codec, ch->spdreg, r) * < sc->ac97rate / 48000; --- > r = (speed * 48000) / sc->ac97rate; > ch->spd = (ac97_setrate(sc->codec, ch->spdreg, r) * sc->ac97rate) / 48000; 299c298 < return 48000; --- > ch->spd = 48000; 300a300 > return ch->spd; 326c326 < ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE, 1); --- > ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE, 1); 447c447,453 < /* Grab audio from input for fixed interval and compare how --- > struct sc_chinfo *ch = &sc->ch[1]; > struct timeval t1, t2; > u_int8_t ociv, nciv; > u_int32_t wait_us, actual_48k_rate, bytes; > > /* > * Grab audio from input for fixed interval and compare how 450,454c456,458 < * generated. */ < struct sc_chinfo *ch = &sc->ch[1]; < u_int16_t target_picb, actual_picb; < u_int32_t wait_us, actual_48k_rate; < --- > * generated. > */ > 456,470d459 < < ichchan_setspeed(0, ch, 48000); < ichchan_setblocksize(0, ch, ICH_DEFAULT_BUFSZ); < < target_picb = ch->dtbl[0].length / 2; /* half interrupt interval */ < wait_us = target_picb * 1000 / (2 * 48); /* (2 == stereo -> mono) */ < < if (bootverbose) < device_printf(sc->dev, "Calibration interval %d us\n", < wait_us); < < ichchan_trigger(0, ch, PCMTRIG_START); < DELAY(wait_us); < actual_picb = ich_rd(sc, ch->regbase + ICH_REG_X_PICB, 2); < ichchan_trigger(0, ch, PCMTRIG_ABORT); 472,473c461,509 < actual_48k_rate = 48000 * (2 * target_picb - actual_picb) / < (target_picb); --- > bytes = sndbuf_getsize(ch->buffer) / 2; > ichchan_setblocksize(0, ch, bytes); > > /* > * our data format is stereo, 16 bit so each sample is 4 bytes. > * assuming we get 48000 samples per second, we get 192000 bytes/sec. > * we're going to start recording with interrupts disabled and measure > * the time taken for one block to complete. we know the block size, > * we know the time in microseconds, we calculate the sample rate: > * > * actual_rate [bps] = bytes / (time [s] * 4) > * actual_rate [bps] = (bytes * 1000000) / (time [us] * 4) > * actual_rate [Hz] = (bytes * 250000) / time [us] > */ > > /* prepare */ > ociv = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1); > nciv = ociv; > ich_wr(sc, ch->regbase + ICH_REG_X_BDBAR, (u_int32_t)vtophys(ch->dtbl), 4); > > /* start */ > microtime(&t1); > ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM, 1); > > /* wait */ > while (nciv == ociv) { > microtime(&t2); > if (t2.tv_sec - t1.tv_sec > 1) > break; > nciv = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1); > } > microtime(&t2); > > /* stop */ > ich_wr(sc, ch->regbase + ICH_REG_X_CR, 0, 1); > > /* reset */ > DELAY(100); > ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RR, 1); > > /* turn time delta into us */ > wait_us = ((t2.tv_sec - t1.tv_sec) * 1000000) + t2.tv_usec - t1.tv_usec; > > if (nciv == ociv) { > device_printf(sc->dev, "ac97 link rate calibration timed out after %d us\n", wait_us); > return 0; > } > > actual_48k_rate = (bytes * 250000) / wait_us; 475c511 < if (actual_48k_rate > 48500 || actual_48k_rate < 47500) { --- > if (actual_48k_rate < 47500 || actual_48k_rate > 48500) { 481,485c517,522 < if (bootverbose) < device_printf(sc->dev, < "Estimated AC97 link rate %d, using %d\n", < actual_48k_rate, sc->ac97rate); < --- > if (bootverbose || sc->ac97rate != 48000) { > device_printf(sc->dev, "measured ac97 link rate at %d Hz", actual_48k_rate); > if (sc->ac97rate != actual_48k_rate) > printf(", will use %d Hz", sc->ac97rate); > printf("\n"); > } 598a636,642 > sc->irqid = 0; > sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); > if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ich_intr, sc, &sc->ih)) { > device_printf(dev, "unable to map interrupt\n"); > goto bad; > } > 615,621d658 < sc->irqid = 0; < sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); < if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ich_intr, sc, &sc->ih)) { < device_printf(dev, "unable to map interrupt\n"); < goto bad; < } < 641a679,682 > if (sc->ih) > bus_teardown_intr(dev, sc->irq, sc->ih); > if (sc->irq) > bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 648,651d688 < if (sc->ih) < bus_teardown_intr(dev, sc->irq, sc->ih); < if (sc->irq) < bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 676a714,732 > ich_pci_suspend(device_t dev) > { > struct sc_info *sc; > int i; > > sc = pcm_getdevinfo(dev); > for (i = 0 ; i < 3; i++) { > sc->ch[i].run_save = sc->ch[i].run; > if (sc->ch[i].run) { > ichchan_trigger(0, &sc->ch[i], PCMTRIG_ABORT); > } > } > > /* ACLINK shut off */ > ich_wr(sc,ICH_REG_GLOB_CNT, ICH_GLOB_CTL_SHUT, 4); > return 0; > } > > static int 679a736 > int i; 692a750,758 > /* Re-start DMA engines */ > for (i = 0 ; i < 3; i++) { > struct sc_chinfo *ch = &sc->ch[i]; > if (sc->ch[i].run_save) { > ichchan_setblocksize(0, ch, ch->blksz); > ichchan_setspeed(0, ch, ch->spd); > ichchan_trigger(0, ch, PCMTRIG_START); > } > } 700a767 > DEVMETHOD(device_suspend, ich_pci_suspend),