summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2002-06-27 22:36:01 +0000
committerscottl <scottl@FreeBSD.org>2002-06-27 22:36:01 +0000
commit434f33d82438442b1dab7090fab90db4c3d02cdb (patch)
tree116925c5260c21fad6c9b16703bc142aee7a724f
parent0a087122156c6e3b13e8ed52302709f7bbd480d6 (diff)
downloadFreeBSD-src-434f33d82438442b1dab7090fab90db4c3d02cdb.zip
FreeBSD-src-434f33d82438442b1dab7090fab90db4c3d02cdb.tar.gz
Delay the AC97 calibration until after the system clock has been
calibrated. This fixes the problem where playback and recording do not run at the correct speed. It probably also eliminates the need for the hacks/workarounds/sysctl's that were previously devised to deal with this, but I will leave that for a different time. Reviewed by: orion
-rw-r--r--sys/dev/sound/pci/ich.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/sys/dev/sound/pci/ich.c b/sys/dev/sound/pci/ich.c
index 4b1cb18..603641f 100644
--- a/sys/dev/sound/pci/ich.c
+++ b/sys/dev/sound/pci/ich.c
@@ -85,6 +85,8 @@ struct sc_info {
struct sc_chinfo ch[3];
int ac97rate;
struct ich_desc *dtbl;
+ struct intr_config_hook intrhook;
+ int use_intrhook;
};
/* -------------------------------------------------------------------- */
@@ -455,13 +457,20 @@ ich_initsys(struct sc_info* sc)
/* Calibrate card (some boards are overclocked and need scaling) */
static
-unsigned int ich_calibrate(struct sc_info *sc)
+void ich_calibrate(void *arg)
{
- struct sc_chinfo *ch = &sc->ch[1];
+ struct sc_info *sc;
+ struct sc_chinfo *ch;
struct timeval t1, t2;
u_int8_t ociv, nciv;
u_int32_t wait_us, actual_48k_rate, bytes;
+ sc = (struct sc_info *)arg;
+ ch = &sc->ch[1];
+
+ if (sc->use_intrhook)
+ config_intrhook_disestablish(&sc->intrhook);
+
/*
* Grab audio from input for fixed interval and compare how
* much we actually get with what we expect. Interval needs
@@ -516,7 +525,7 @@ unsigned int ich_calibrate(struct sc_info *sc)
if (nciv == ociv) {
device_printf(sc->dev, "ac97 link rate calibration timed out after %d us\n", wait_us);
- return 0;
+ return;
}
actual_48k_rate = (bytes * 250000) / wait_us;
@@ -534,7 +543,7 @@ unsigned int ich_calibrate(struct sc_info *sc)
printf("\n");
}
- return sc->ac97rate;
+ return;
}
/* -------------------------------------------------------------------- */
@@ -708,7 +717,15 @@ ich_pci_attach(device_t dev)
pcm_setstatus(dev, status);
ich_initsys(sc);
- ich_calibrate(sc);
+
+ sc->intrhook.ich_func = ich_calibrate;
+ sc->intrhook.ich_arg = sc;
+ sc->use_intrhook = 1;
+ if (config_intrhook_establish(&sc->intrhook) != 0) {
+ device_printf(dev, "Cannot establish calibration hook, will calibrate now\n");
+ sc->use_intrhook = 0;
+ ich_calibrate(sc);
+ }
return 0;
OpenPOWER on IntegriCloud