When the DAC claims to support variable rate it doesn't seem to

always do this, so do some extra chechs and fall back on fixed rate.
This commit is contained in:
augustss 2002-04-11 10:54:23 +00:00
parent 876d3c9146
commit 3f41adf3be
1 changed files with 42 additions and 28 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: auich.c,v 1.16 2002/03/23 17:17:11 kent Exp $ */ /* $NetBSD: auich.c,v 1.17 2002/04/11 10:54:23 augustss Exp $ */
/*- /*-
* Copyright (c) 2000 The NetBSD Foundation, Inc. * Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -80,7 +80,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.16 2002/03/23 17:17:11 kent Exp $"); __KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.17 2002/04/11 10:54:23 augustss Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -182,6 +182,8 @@ struct auich_softc {
u_int16_t ext_status; u_int16_t ext_status;
}; };
#define FIXED_RATE 48000
/* Debug */ /* Debug */
#ifdef AUDIO_DEBUG #ifdef AUDIO_DEBUG
#define DPRINTF(l,x) do { if (auich_debug & (l)) printf x; } while(0) #define DPRINTF(l,x) do { if (auich_debug & (l)) printf x; } while(0)
@ -230,6 +232,8 @@ int auich_allocmem(struct auich_softc *, size_t, size_t,
int auich_freemem(struct auich_softc *, struct auich_dma *); int auich_freemem(struct auich_softc *, struct auich_dma *);
void auich_powerhook(int, void *); void auich_powerhook(int, void *);
int auich_set_rate(struct auich_softc *sc, int mode, uint srate);
struct audio_hw_if auich_hw_if = { struct audio_hw_if auich_hw_if = {
auich_open, auich_open,
@ -398,11 +402,17 @@ auich_attach(struct device *parent, struct device *self, void *aux)
if ((ext_id & AC97_CODEC_DOES_MICVRA) !=0) if ((ext_id & AC97_CODEC_DOES_MICVRA) !=0)
ext_status |= AC97_ENAB_MICVRA; ext_status |= AC97_ENAB_MICVRA;
auich_write_codec(sc, AC97_REG_EXTENDED_STATUS, ext_status); auich_write_codec(sc, AC97_REG_EXTENDED_STATUS, ext_status);
sc->sc_fixed_rate = 0;
/* so it claims to do variable rate, let's make sure */
if (auich_set_rate(sc, AUMODE_PLAY, 44100) == 44100)
sc->sc_fixed_rate = 0;
else
sc->sc_fixed_rate = FIXED_RATE;
} else { } else {
sc->sc_fixed_rate = 48000; sc->sc_fixed_rate = FIXED_RATE;
printf("%s: warning, fixed rate codec\n", sc->sc_dev.dv_xname);
} }
if (sc->sc_fixed_rate)
printf("%s: warning, fixed rate codec\n", sc->sc_dev.dv_xname);
audio_attach_mi(&auich_hw_if, sc, &sc->sc_dev); audio_attach_mi(&auich_hw_if, sc, &sc->sc_dev);
@ -574,6 +584,29 @@ auich_query_encoding(void *v, struct audio_encoding *aep)
} }
} }
int
auich_set_rate(struct auich_softc *sc, int mode, uint srate)
{
u_int16_t val, rate, inout;
inout = mode == AUMODE_PLAY ? ICH_PM_PCMO : ICH_PM_PCMI;
auich_read_codec(sc, AC97_REG_POWER, &val);
auich_write_codec(sc, AC97_REG_POWER, val | inout);
if (mode == AUMODE_PLAY) {
auich_write_codec(sc, AC97_REG_PCM_FRONT_DAC_RATE, srate);
auich_read_codec(sc, AC97_REG_PCM_FRONT_DAC_RATE, &rate);
} else {
auich_write_codec(sc, AC97_REG_PCM_LR_ADC_RATE, srate);
auich_read_codec(sc, AC97_REG_PCM_LR_ADC_RATE, &rate);
}
auich_write_codec(sc, AC97_REG_POWER, val);
return rate;
}
int int
auich_set_params(void *v, int setmode, int usemode, struct audio_params *play, auich_set_params(void *v, int setmode, int usemode, struct audio_params *play,
struct audio_params *rec) struct audio_params *rec)
@ -581,7 +614,6 @@ auich_set_params(void *v, int setmode, int usemode, struct audio_params *play,
struct auich_softc *sc = v; struct auich_softc *sc = v;
struct audio_params *p; struct audio_params *p;
int mode; int mode;
u_int16_t val, rate, inout;
for (mode = AUMODE_RECORD; mode != -1; for (mode = AUMODE_RECORD; mode != -1;
mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) { mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
@ -592,8 +624,6 @@ auich_set_params(void *v, int setmode, int usemode, struct audio_params *play,
if (p == NULL) if (p == NULL)
continue; continue;
inout = mode == AUMODE_PLAY ? ICH_PM_PCMO : ICH_PM_PCMI;
if ((p->sample_rate != 8000) && if ((p->sample_rate != 8000) &&
(p->sample_rate != 11025) && (p->sample_rate != 11025) &&
(p->sample_rate != 16000) && (p->sample_rate != 16000) &&
@ -685,27 +715,11 @@ auich_set_params(void *v, int setmode, int usemode, struct audio_params *play,
return (EINVAL); return (EINVAL);
} }
auich_read_codec(sc, AC97_REG_POWER, &val); if (sc->sc_fixed_rate)
auich_write_codec(sc, AC97_REG_POWER, val | inout);
if (sc->sc_fixed_rate) {
p->hw_sample_rate = sc->sc_fixed_rate; p->hw_sample_rate = sc->sc_fixed_rate;
} else { else
if (mode == AUMODE_PLAY) { p->hw_sample_rate = auich_set_rate(sc, mode,
auich_write_codec(sc, AC97_REG_PCM_FRONT_DAC_RATE, p->sample_rate);
p->sample_rate);
auich_read_codec(sc, AC97_REG_PCM_FRONT_DAC_RATE,
&rate);
} else {
auich_write_codec(sc, AC97_REG_PCM_LR_ADC_RATE,
p->sample_rate);
auich_read_codec(sc, AC97_REG_PCM_LR_ADC_RATE,
&rate);
}
p->hw_sample_rate = rate;
}
auich_write_codec(sc, AC97_REG_POWER, val);
} }
return (0); return (0);