diff --git a/sys/dev/sound/pci/ich.c b/sys/dev/sound/pci/ich.c index 44213230f22a..328540c6b6e3 100644 --- a/sys/dev/sound/pci/ich.c +++ b/sys/dev/sound/pci/ich.c @@ -79,6 +79,7 @@ struct sc_info { struct ac97_info *codec; struct sc_chinfo ch[3]; + int ac97rate; struct ich_desc *dtbl; }; @@ -284,10 +285,16 @@ ichchan_setspeed(kobj_t obj, void *data, u_int32_t speed) struct sc_chinfo *ch = data; struct sc_info *sc = ch->parent; - if (ch->spdreg) - return ac97_setrate(sc->codec, ch->spdreg, speed); - else + if (ch->spdreg) { + int r; + if (sc->ac97rate <= 32000 || sc->ac97rate >= 64000) + sc->ac97rate = 48000; + r = speed * 48000 / sc->ac97rate; + return ac97_setrate(sc->codec, ch->spdreg, r) * + sc->ac97rate / 48000; + } else { return 48000; + } } static int @@ -399,6 +406,22 @@ ich_intr(void *p) } } +/* ------------------------------------------------------------------------- */ +/* Sysctl to control ac97 speed (some boards overclocked ac97). */ + +static int +ich_initsys(struct sc_info* sc) +{ +#ifdef SND_DYNSYSCTL + SYSCTL_ADD_INT(snd_sysctl_tree(sc->dev), + SYSCTL_CHILDREN(snd_sysctl_tree_top(sc->dev)), + OID_AUTO, "ac97rate", CTLFLAG_RW, + &sc->ac97rate, 48000, + "AC97 link rate (default = 48000)"); +#endif /* SND_DYNSYSCTL */ + return 0; +} + /* -------------------------------------------------------------------- */ /* Probe and attach the card */ @@ -549,6 +572,8 @@ ich_pci_attach(device_t dev) pcm_setstatus(dev, status); + ich_initsys(sc); + return 0; bad: