AD1845 on my AlphaStation 255 doesn't match the AD1845 doc.

Try to detect AD1845 (unfortunately this is not always correct)
and work around the problems.
This commit is contained in:
itohy 2001-11-04 08:08:25 +00:00
parent e8ba741b16
commit c0f59fbbeb
3 changed files with 52 additions and 10 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ad1848.c,v 1.10 2001/01/18 20:28:17 jdolecek Exp $ */
/* $NetBSD: ad1848.c,v 1.11 2001/11/04 08:08:25 itohy Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -126,6 +126,15 @@
#include <dev/isa/cs4231var.h>
#endif
/*
* AD1845 on some machines don't match the AD1845 doc
* and defining AD1845_HACK to 1 works around the problems.
* options AD1845_HACK=0 should work if you have ``correct'' one.
*/
#ifndef AD1845_HACK
#define AD1845_HACK 1 /* weird mixer, can't play slinear_be */
#endif
#ifdef AUDIO_DEBUG
#define DPRINTF(x) if (ad1848debug) printf x
int ad1848debug = 0;
@ -415,7 +424,11 @@ ad1848_attach(sc)
ad1848_set_channel_gain(sc, AD1848_MONITOR_CHANNEL, &vol_0);
ad1848_set_channel_gain(sc, AD1848_AUX1_CHANNEL, &vol_mid); /* CD volume */
sc->mute[AD1848_MONITOR_CHANNEL] = MUTE_ALL;
if (sc->mode >= 2) {
if (sc->mode >= 2
#if AD1845_HACK
&& sc->is_ad1845 == 0
#endif
) {
ad1848_set_channel_gain(sc, AD1848_AUX2_CHANNEL, &vol_mid); /* CD volume */
ad1848_set_channel_gain(sc, AD1848_LINE_CHANNEL, &vol_mid);
ad1848_set_channel_gain(sc, AD1848_MONO_CHANNEL, &vol_0);
@ -845,7 +858,11 @@ ad1848_query_encoding(addr, fp)
strcpy(fp->name, AudioEslinear_be);
fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
fp->precision = 16;
fp->flags = sc->mode == 1 ? AUDIO_ENCODINGFLAG_EMULATED : 0;
fp->flags = sc->mode == 1
#if AD1845_HACK
|| sc->is_ad1845
#endif
? AUDIO_ENCODINGFLAG_EMULATED : 0;
break;
/* emulate some modes */
@ -869,7 +886,7 @@ ad1848_query_encoding(addr, fp)
break;
case 8: /* only on CS4231 */
if (sc->mode == 1)
if (sc->mode == 1 || sc->is_ad1845)
return EINVAL;
strcpy(fp->name, AudioEadpcm);
fp->encoding = AUDIO_ENCODING_ADPCM;
@ -907,7 +924,11 @@ ad1848_set_params(addr, setmode, usemode, p, r)
}
break;
case AUDIO_ENCODING_SLINEAR_BE:
if (p->precision == 16 && sc->mode == 1) {
if (p->precision == 16 && (sc->mode == 1
#if AD1845_HACK
|| sc->is_ad1845
#endif
)) {
enc = AUDIO_ENCODING_SLINEAR_LE;
pswcode = rswcode = swap_bytes;
}
@ -920,7 +941,11 @@ ad1848_set_params(addr, setmode, usemode, p, r)
break;
case AUDIO_ENCODING_ULINEAR_BE:
if (p->precision == 16) {
if (sc->mode == 1) {
if (sc->mode == 1
#if AD1845_HACK
|| sc->is_ad1845
#endif
) {
enc = AUDIO_ENCODING_SLINEAR_LE;
pswcode = swap_bytes_change_sign16_le;
rswcode = change_sign16_swap_bytes_le;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ad1848var.h,v 1.7 2000/06/26 04:56:18 simonb Exp $ */
/* $NetBSD: ad1848var.h,v 1.8 2001/11/04 08:08:26 itohy Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -101,6 +101,7 @@ struct ad1848_softc {
char *chip_name;
int mode;
int is_ad1845;
u_int precision; /* 8/16 bits */
int channels;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ad1848_isa.c,v 1.18 2000/12/20 21:06:41 thorpej Exp $ */
/* $NetBSD: ad1848_isa.c,v 1.19 2001/11/04 08:08:26 itohy Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -191,7 +191,7 @@ ad1848_isa_probe(isc)
{
struct ad1848_softc *sc = &isc->sc_ad1848;
u_char tmp, tmp1 = 0xff, tmp2 = 0xff;
int i;
int i, t;
sc->sc_readreg = ad1848_isa_read;
sc->sc_writereg = ad1848_isa_write;
@ -249,6 +249,14 @@ ad1848_isa_probe(isc)
tmp = ad_read(sc, SP_MISC_INFO);
ad_write(sc, SP_MISC_INFO, (~tmp) & 0x0f);
/* Here, AD1845 may sometimes be busy. Wait til it becomes ready. */
for (t = 0; t < 100000 && ADREAD(sc, AD1848_IADDR) & SP_IN_INIT; t++)
;
#ifdef AUDIO_DEBUG
if (t)
DPRINTF(("ad1848_isa_probe: t %d\n", t));
#endif
if ((tmp & 0x0f) != ((tmp1 = ad_read(sc, SP_MISC_INFO)) & 0x0f)) {
DPRINTF(("ad_detect_D (%x)\n", tmp1));
goto bad;
@ -344,7 +352,15 @@ ad1848_isa_probe(isc)
break;
case 0x80:
/* XXX I25 no good, AD1845 same as CS4231 */
sc->chip_name = "CS4231 or AD1845";
/*
* XXX
* This test is correct only after reset
*/
if (ad_read(sc, 17) & 0xf0) {
sc->chip_name = "AD1845";
sc->is_ad1845 = 1;
} else
sc->chip_name = "CS4231";
break;
case 0x82:
sc->chip_name = "CS4232";