Support for 4ch/6ch audio playback with VT8233/VT8235.

This commit is contained in:
kent 2002-10-16 15:27:28 +00:00
parent 706c1ce906
commit 565a6b3384
2 changed files with 164 additions and 121 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: auvia.c,v 1.26 2002/10/08 13:10:24 kent Exp $ */ /* $NetBSD: auvia.c,v 1.27 2002/10/16 15:27:28 kent Exp $ */
/*- /*-
* Copyright (c) 2000 The NetBSD Foundation, Inc. * Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -47,7 +47,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: auvia.c,v 1.26 2002/10/08 13:10:24 kent Exp $"); __KERNEL_RCSID(0, "$NetBSD: auvia.c,v 1.27 2002/10/16 15:27:28 kent Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
@ -90,7 +90,9 @@ int auvia_match(struct device *, struct cfdata *, void *);
void auvia_attach(struct device *, struct device *, void *); void auvia_attach(struct device *, struct device *, void *);
int auvia_open(void *, int); int auvia_open(void *, int);
void auvia_close(void *); void auvia_close(void *);
int auvia_query_encoding(void *addr, struct audio_encoding *fp); int auvia_query_encoding(void *, struct audio_encoding *);
void auvia_set_params_sub(struct auvia_softc *, struct auvia_softc_chan *,
struct audio_params *);
int auvia_set_params(void *, int, int, struct audio_params *, int auvia_set_params(void *, int, int, struct audio_params *,
struct audio_params *); struct audio_params *);
int auvia_round_blocksize(void *, int); int auvia_round_blocksize(void *, int);
@ -130,6 +132,7 @@ CFATTACH_DECL(auvia, sizeof (struct auvia_softc),
#define AUVIA_PLAY_BASE 0x00 #define AUVIA_PLAY_BASE 0x00
#define AUVIA_RECORD_BASE 0x10 #define AUVIA_RECORD_BASE 0x10
/* *_RP_* are offsets from AUVIA_PLAY_BASE or AUVIA_RECORD_BASE */
#define AUVIA_RP_STAT 0x00 #define AUVIA_RP_STAT 0x00
#define AUVIA_RPSTAT_INTR 0x03 #define AUVIA_RPSTAT_INTR 0x03
#define AUVIA_RP_CONTROL 0x01 #define AUVIA_RP_CONTROL 0x01
@ -140,7 +143,7 @@ CFATTACH_DECL(auvia, sizeof (struct auvia_softc),
#define AUVIA_RPCTRL_STOP 0x04 #define AUVIA_RPCTRL_STOP 0x04
#define AUVIA_RPCTRL_EOL 0x02 #define AUVIA_RPCTRL_EOL 0x02
#define AUVIA_RPCTRL_FLAG 0x01 #define AUVIA_RPCTRL_FLAG 0x01
#define AUVIA_RP_MODE 0x02 #define AUVIA_RP_MODE 0x02 /* 82c686 specific */
#define AUVIA_RPMODE_INTR_FLAG 0x01 #define AUVIA_RPMODE_INTR_FLAG 0x01
#define AUVIA_RPMODE_INTR_EOL 0x02 #define AUVIA_RPMODE_INTR_EOL 0x02
#define AUVIA_RPMODE_STEREO 0x10 #define AUVIA_RPMODE_STEREO 0x10
@ -157,12 +160,30 @@ CFATTACH_DECL(auvia, sizeof (struct auvia_softc),
#define VIA_RP_DMAOPS_COUNT 0x0c #define VIA_RP_DMAOPS_COUNT 0x0c
#define VIA8233_MP_BASE 0x40
/* STAT, CONTROL, DMAOPS_BASE, DMAOPS_COUNT are valid */
#define VIA8233_OFF_MP_FORMAT 0x02
#define VIA8233_MP_FORMAT_8BIT 0x00
#define VIA8233_MP_FORMAT_16BIT 0x80
#define VIA8233_MP_FORMAT_CHANNLE_MASK 0x70 /* 1, 2, 4, 6 */
#define VIA8233_OFF_MP_SCRATCH 0x03
#define VIA8233_OFF_MP_STOP 0x08
#define AUVIA_CODEC_CTL 0x80 #define AUVIA_CODEC_CTL 0x80
#define AUVIA_CODEC_READ 0x00800000 #define AUVIA_CODEC_READ 0x00800000
#define AUVIA_CODEC_BUSY 0x01000000 #define AUVIA_CODEC_BUSY 0x01000000
#define AUVIA_CODEC_PRIVALID 0x02000000 #define AUVIA_CODEC_PRIVALID 0x02000000
#define AUVIA_CODEC_INDEX(x) ((x)<<16) #define AUVIA_CODEC_INDEX(x) ((x)<<16)
#define CH_WRITE1(sc, ch, off, v) \
bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (ch)->sc_base + (off), v)
#define CH_WRITE4(sc, ch, off, v) \
bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (ch)->sc_base + (off), v)
#define CH_READ1(sc, ch, off) \
bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (ch)->sc_base + (off))
#define CH_READ4(sc, ch, off) \
bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (ch)->sc_base + (off))
#define TIMEOUT 50 #define TIMEOUT 50
struct audio_hw_if auvia_hw_if = { struct audio_hw_if auvia_hw_if = {
@ -228,16 +249,19 @@ auvia_attach(struct device *parent, struct device *self, void *aux)
struct pci_attach_args *pa = aux; struct pci_attach_args *pa = aux;
struct auvia_softc *sc = (struct auvia_softc *) self; struct auvia_softc *sc = (struct auvia_softc *) self;
const char *intrstr = NULL; const char *intrstr = NULL;
struct mixer_ctrl ctl;
pci_chipset_tag_t pc = pa->pa_pc; pci_chipset_tag_t pc = pa->pa_pc;
pcitag_t pt = pa->pa_tag; pcitag_t pt = pa->pa_tag;
pci_intr_handle_t ih; pci_intr_handle_t ih;
bus_size_t iosize; bus_size_t iosize;
pcireg_t pr; pcireg_t pr;
int r, i; int r;
if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT8233_AC97) sc->sc_play.sc_base = AUVIA_PLAY_BASE;
sc->sc_record.sc_base = AUVIA_RECORD_BASE;
if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT8233_AC97) {
sc->sc_flags |= AUVIA_FLAGS_VT8233; sc->sc_flags |= AUVIA_FLAGS_VT8233;
sc->sc_play.sc_base = VIA8233_MP_BASE;
}
if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, &sc->sc_iot, if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_IO, 0, &sc->sc_iot,
&sc->sc_ioh, NULL, &iosize)) { &sc->sc_ioh, NULL, &iosize)) {
@ -319,37 +343,6 @@ auvia_attach(struct device *parent, struct device *self, void *aux)
return; return;
} }
/* disable mutes */
for (i = 0; i < 4; i++) {
static struct {
char *class, *device;
} d[] = {
{ AudioCoutputs, AudioNmaster},
{ AudioCinputs, AudioNdac},
{ AudioCinputs, AudioNcd},
{ AudioCinputs, AudioNline},
{ AudioCrecord, AudioNvolume},
};
ctl.type = AUDIO_MIXER_ENUM;
ctl.un.ord = 0;
ctl.dev = sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if,
d[i].class, d[i].device, AudioNmute);
auvia_set_port(sc, &ctl);
}
/* set a reasonable default volume */
ctl.type = AUDIO_MIXER_VALUE;
ctl.un.value.num_channels = 2;
ctl.un.value.level[AUDIO_MIXER_LEVEL_LEFT] = \
ctl.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = 199;
ctl.dev = sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if,
AudioCoutputs, AudioNmaster, NULL);
auvia_set_port(sc, &ctl);
audio_attach_mi(&auvia_hw_if, sc, &sc->sc_dev); audio_attach_mi(&auvia_hw_if, sc, &sc->sc_dev);
} }
@ -540,16 +533,58 @@ auvia_query_encoding(void *addr, struct audio_encoding *fp)
} }
} }
void
auvia_set_params_sub(struct auvia_softc *sc, struct auvia_softc_chan *ch,
struct audio_params *p)
{
u_int32_t v;
u_int16_t regval;
if (!(sc->sc_flags & AUVIA_FLAGS_VT8233)) {
regval = (p->channels == 2 ? AUVIA_RPMODE_STEREO : 0)
| (p->precision * p->factor == 16 ?
AUVIA_RPMODE_16BIT : 0)
| AUVIA_RPMODE_INTR_FLAG | AUVIA_RPMODE_INTR_EOL
| AUVIA_RPMODE_AUTOSTART;
ch->sc_reg = regval;
} else if (ch->sc_base != VIA8233_MP_BASE) {
v = CH_READ4(sc, ch, VIA8233_RP_RATEFMT);
v &= ~(VIA8233_RATEFMT_48K | VIA8233_RATEFMT_STEREO
| VIA8233_RATEFMT_16BIT);
v |= VIA8233_RATEFMT_48K * (p->sample_rate / 20)
/ (48000 / 20);
if (p->channels == 2)
v |= VIA8233_RATEFMT_STEREO;
if (p->precision == 16)
v |= VIA8233_RATEFMT_16BIT;
CH_WRITE4(sc, ch, VIA8233_RP_RATEFMT, v);
} else {
static const u_int32_t slottab[7] =
{ 0, 0xff000011, 0xff000021, 0,
0xff004321, 0, 0xff436521};
regval = (p->hw_precision == 16
? VIA8233_MP_FORMAT_16BIT : VIA8233_MP_FORMAT_8BIT)
| (p->hw_channels << 4);
CH_WRITE1(sc, ch, VIA8233_OFF_MP_FORMAT, regval);
CH_WRITE4(sc, ch, VIA8233_OFF_MP_STOP, slottab[p->hw_channels]);
}
}
int int
auvia_set_params(void *addr, int setmode, int usemode, auvia_set_params(void *addr, int setmode, int usemode,
struct audio_params *play, struct audio_params *rec) struct audio_params *play, struct audio_params *rec)
{ {
struct auvia_softc *sc = addr; struct auvia_softc *sc = addr;
struct auvia_softc_chan *ch;
struct audio_params *p; struct audio_params *p;
u_int16_t regval; struct ac97_codec_if* codec;
int reg, mode, base; int reg, mode;
u_int16_t ext_id;
codec = sc->codec_if;
/* for mode in (RECORD, PLAY) */ /* for mode in (RECORD, PLAY) */
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) {
@ -558,43 +593,54 @@ auvia_set_params(void *addr, int setmode, int usemode,
if (mode == AUMODE_PLAY ) { if (mode == AUMODE_PLAY ) {
p = play; p = play;
base = AUVIA_PLAY_BASE; ch = &sc->sc_play;
} else { } else {
p = rec; p = rec;
base = AUVIA_RECORD_BASE; ch = &sc->sc_record;
} }
if (sc->sc_flags & AUVIA_FLAGS_VT8233) { if (ch->sc_base == VIA8233_MP_BASE) {
u_int32_t v = bus_space_read_4(sc->sc_iot, sc->sc_ioh, ext_id = codec->vtbl->get_extcaps(codec);
base + VIA8233_RP_RATEFMT) & ~(VIA8233_RATEFMT_48K if (p->channels == 1) {
| VIA8233_RATEFMT_STEREO | VIA8233_RATEFMT_16BIT); /* ok */
} else if (p->channels == 2) {
v |= VIA8233_RATEFMT_48K * (p->sample_rate / 20) /* ok */
/ (48000 / 20); } else if (p->channels == 4
&& ext_id & AC97_EXT_AUDIO_SDAC) {
if (p->channels == 2) /* ok */
v |= VIA8233_RATEFMT_STEREO; #define BITS_6CH (AC97_EXT_AUDIO_SDAC | AC97_EXT_AUDIO_CDAC | AC97_EXT_AUDIO_LDAC)
if( p->precision == 16) } else if (p->channels == 6
v |= VIA8233_RATEFMT_16BIT; && (ext_id & BITS_6CH) == BITS_6CH) {
/* ok */
bus_space_write_4(sc->sc_iot, sc->sc_ioh, } else {
base + VIA8233_RP_RATEFMT, v); return (EINVAL);
}
} else {
if (p->channels != 1 && p->channels != 2)
return (EINVAL);
} }
if (p->sample_rate < 4000 || p->sample_rate > 48000 || if (p->sample_rate < 4000 || p->sample_rate > 48000 ||
(p->precision != 8 && p->precision != 16) || (p->precision != 8 && p->precision != 16))
(p->channels != 1 && p->channels != 2))
return (EINVAL); return (EINVAL);
reg = mode == AUMODE_PLAY ? reg = mode == AUMODE_PLAY ?
AC97_REG_PCM_FRONT_DAC_RATE : AC97_REG_PCM_LR_ADC_RATE; AC97_REG_PCM_FRONT_DAC_RATE : AC97_REG_PCM_LR_ADC_RATE;
if (IS_FIXED_RATE(sc->codec_if)) { if (IS_FIXED_RATE(codec)) {
/* Enable aurateconv */ /* Enable aurateconv */
p->hw_sample_rate = AC97_SINGLE_RATE; p->hw_sample_rate = AC97_SINGLE_RATE;
} else { } else {
if (sc->codec_if->vtbl->set_rate(sc->codec_if, reg, if (codec->vtbl->set_rate(codec, reg, &p->sample_rate))
&p->sample_rate)) return (EINVAL);
reg = AC97_REG_PCM_SURR_DAC_RATE;
if (p->channels >= 4
&& codec->vtbl->set_rate(codec, reg,
&p->sample_rate))
return (EINVAL);
reg = AC97_REG_PCM_LFE_DAC_RATE;
if (p->channels == 6
&& codec->vtbl->set_rate(codec, reg,
&p->sample_rate))
return (EINVAL); return (EINVAL);
} }
@ -602,14 +648,19 @@ auvia_set_params(void *addr, int setmode, int usemode,
p->sw_code = 0; p->sw_code = 0;
switch (p->encoding) { switch (p->encoding) {
case AUDIO_ENCODING_SLINEAR_BE: case AUDIO_ENCODING_SLINEAR_BE:
if (p->precision == 16) if (p->precision == 16) {
p->sw_code = swap_bytes; p->sw_code = swap_bytes;
else p->hw_encoding = AUDIO_ENCODING_SLINEAR_LE;
} else {
p->sw_code = change_sign8; p->sw_code = change_sign8;
p->hw_encoding = AUDIO_ENCODING_ULINEAR;
}
break; break;
case AUDIO_ENCODING_SLINEAR_LE: case AUDIO_ENCODING_SLINEAR_LE:
if (p->precision != 16) if (p->precision != 16) {
p->sw_code = change_sign8; p->sw_code = change_sign8;
p->hw_encoding = AUDIO_ENCODING_ULINEAR;
}
break; break;
case AUDIO_ENCODING_ULINEAR_BE: case AUDIO_ENCODING_ULINEAR_BE:
if (p->precision == 16) { if (p->precision == 16) {
@ -617,41 +668,45 @@ auvia_set_params(void *addr, int setmode, int usemode,
p->sw_code = swap_bytes_change_sign16_le; p->sw_code = swap_bytes_change_sign16_le;
else else
p->sw_code = change_sign16_swap_bytes_le; p->sw_code = change_sign16_swap_bytes_le;
p->hw_encoding = AUDIO_ENCODING_SLINEAR_LE;
} }
break; break;
case AUDIO_ENCODING_ULINEAR_LE: case AUDIO_ENCODING_ULINEAR_LE:
if (p->precision == 16) if (p->precision == 16) {
p->sw_code = change_sign16_le; p->sw_code = change_sign16_le;
p->hw_encoding = AUDIO_ENCODING_SLINEAR_LE;
}
break; break;
case AUDIO_ENCODING_ULAW: case AUDIO_ENCODING_ULAW:
if (p->precision != 8)
return (EINVAL);
if (mode == AUMODE_PLAY) { if (mode == AUMODE_PLAY) {
p->factor = 2; p->factor = 2;
p->sw_code = mulaw_to_slinear16_le; p->sw_code = mulaw_to_slinear16_le;
} else p->hw_encoding = AUDIO_ENCODING_SLINEAR_LE;
p->hw_precision = 16;
} else {
p->sw_code = ulinear8_to_mulaw; p->sw_code = ulinear8_to_mulaw;
p->hw_encoding = AUDIO_ENCODING_ULINEAR;
}
break; break;
case AUDIO_ENCODING_ALAW: case AUDIO_ENCODING_ALAW:
if (p->precision != 8)
return (EINVAL);
if (mode == AUMODE_PLAY) { if (mode == AUMODE_PLAY) {
p->factor = 2; p->factor = 2;
p->sw_code = alaw_to_slinear16_le; p->sw_code = alaw_to_slinear16_le;
} else p->hw_encoding = AUDIO_ENCODING_SLINEAR_LE;
p->hw_precision = 16;
} else {
p->sw_code = ulinear8_to_alaw; p->sw_code = ulinear8_to_alaw;
p->hw_encoding = AUDIO_ENCODING_ULINEAR;
}
break; break;
default: default:
return (EINVAL); return (EINVAL);
} }
auvia_set_params_sub(sc, ch, p);
regval = (p->channels == 2 ? AUVIA_RPMODE_STEREO : 0)
| (p->precision * p->factor == 16 ?
AUVIA_RPMODE_16BIT : 0)
| AUVIA_RPMODE_INTR_FLAG | AUVIA_RPMODE_INTR_EOL
| AUVIA_RPMODE_AUTOSTART;
if (mode == AUMODE_PLAY) {
sc->sc_play.sc_reg = regval;
} else {
sc->sc_record.sc_reg = regval;
}
} }
return 0; return 0;
@ -669,10 +724,9 @@ int
auvia_halt_output(void *addr) auvia_halt_output(void *addr)
{ {
struct auvia_softc *sc = addr; struct auvia_softc *sc = addr;
struct auvia_softc_chan *ch = &(sc->sc_play);
bus_space_write_1(sc->sc_iot, sc->sc_ioh, CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_TERMINATE);
AUVIA_PLAY_BASE + AUVIA_RP_CONTROL, AUVIA_RPCTRL_TERMINATE);
return 0; return 0;
} }
@ -681,10 +735,9 @@ int
auvia_halt_input(void *addr) auvia_halt_input(void *addr)
{ {
struct auvia_softc *sc = addr; struct auvia_softc *sc = addr;
struct auvia_softc_chan *ch = &(sc->sc_record);
bus_space_write_1(sc->sc_iot, sc->sc_ioh, CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_TERMINATE);
AUVIA_PLAY_BASE + AUVIA_RP_CONTROL, AUVIA_RPCTRL_TERMINATE);
return 0; return 0;
} }
@ -949,24 +1002,20 @@ auvia_trigger_output(void *addr, void *start, void *end,
ch->sc_intr = intr; ch->sc_intr = intr;
ch->sc_arg = arg; ch->sc_arg = arg;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, CH_WRITE4(sc, ch, AUVIA_RP_DMAOPS_BASE,
AUVIA_PLAY_BASE + AUVIA_RP_DMAOPS_BASE,
ch->sc_dma_ops_dma->map->dm_segs[0].ds_addr); ch->sc_dma_ops_dma->map->dm_segs[0].ds_addr);
if (sc->sc_flags & AUVIA_FLAGS_VT8233) { if (sc->sc_flags & AUVIA_FLAGS_VT8233) {
bus_space_write_1(sc->sc_iot, sc->sc_ioh, if (ch->sc_base != VIA8233_MP_BASE) {
AUVIA_PLAY_BASE + VIA8233_RP_DXS_LVOL, 0); CH_WRITE1(sc, ch, VIA8233_RP_DXS_LVOL, 0);
bus_space_write_1(sc->sc_iot, sc->sc_ioh, CH_WRITE1(sc, ch, VIA8233_RP_DXS_RVOL, 0);
AUVIA_PLAY_BASE + VIA8233_RP_DXS_RVOL, 0); }
bus_space_write_1(sc->sc_iot, sc->sc_ioh, CH_WRITE1(sc, ch, AUVIA_RP_CONTROL,
AUVIA_PLAY_BASE + AUVIA_RP_CONTROL,
AUVIA_RPCTRL_START | AUVIA_RPCTRL_AUTOSTART | AUVIA_RPCTRL_START | AUVIA_RPCTRL_AUTOSTART |
AUVIA_RPCTRL_STOP | AUVIA_RPCTRL_EOL | AUVIA_RPCTRL_FLAG); AUVIA_RPCTRL_STOP | AUVIA_RPCTRL_EOL | AUVIA_RPCTRL_FLAG);
} else { } else {
bus_space_write_1(sc->sc_iot, sc->sc_ioh, CH_WRITE1(sc, ch, AUVIA_RP_MODE, ch->sc_reg);
AUVIA_PLAY_BASE + AUVIA_RP_MODE, ch->sc_reg); CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_START);
bus_space_write_1(sc->sc_iot, sc->sc_ioh,
AUVIA_PLAY_BASE + AUVIA_RP_CONTROL, AUVIA_RPCTRL_START);
} }
return 0; return 0;
@ -996,24 +1045,18 @@ auvia_trigger_input(void *addr, void *start, void *end,
ch->sc_intr = intr; ch->sc_intr = intr;
ch->sc_arg = arg; ch->sc_arg = arg;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, CH_WRITE4(sc, ch, AUVIA_RP_DMAOPS_BASE,
AUVIA_RECORD_BASE + AUVIA_RP_DMAOPS_BASE, ch->sc_dma_ops_dma->map->dm_segs[0].ds_addr);
ch->sc_dma_ops_dma->map->dm_segs[0].ds_addr);
if (sc->sc_flags & AUVIA_FLAGS_VT8233) { if (sc->sc_flags & AUVIA_FLAGS_VT8233) {
bus_space_write_1(sc->sc_iot, sc->sc_ioh, CH_WRITE1(sc, ch, VIA8233_RP_DXS_LVOL, 0);
AUVIA_RECORD_BASE + VIA8233_RP_DXS_LVOL, 0); CH_WRITE1(sc, ch, VIA8233_RP_DXS_RVOL, 0);
bus_space_write_1(sc->sc_iot, sc->sc_ioh, CH_WRITE1(sc, ch, AUVIA_RP_CONTROL,
AUVIA_RECORD_BASE + VIA8233_RP_DXS_RVOL, 0);
bus_space_write_1(sc->sc_iot, sc->sc_ioh,
AUVIA_RECORD_BASE + AUVIA_RP_CONTROL,
AUVIA_RPCTRL_START | AUVIA_RPCTRL_AUTOSTART | AUVIA_RPCTRL_START | AUVIA_RPCTRL_AUTOSTART |
AUVIA_RPCTRL_STOP | AUVIA_RPCTRL_EOL | AUVIA_RPCTRL_FLAG); AUVIA_RPCTRL_STOP | AUVIA_RPCTRL_EOL | AUVIA_RPCTRL_FLAG);
} else { } else {
bus_space_write_1(sc->sc_iot, sc->sc_ioh, CH_WRITE1(sc, ch, AUVIA_RP_MODE, ch->sc_reg);
AUVIA_RECORD_BASE + AUVIA_RP_MODE, ch->sc_reg); CH_WRITE1(sc, ch, AUVIA_RP_CONTROL, AUVIA_RPCTRL_START);
bus_space_write_1(sc->sc_iot, sc->sc_ioh,
AUVIA_RECORD_BASE + AUVIA_RP_CONTROL, AUVIA_RPCTRL_START);
} }
return 0; return 0;
@ -1024,32 +1067,31 @@ int
auvia_intr(void *arg) auvia_intr(void *arg)
{ {
struct auvia_softc *sc = arg; struct auvia_softc *sc = arg;
struct auvia_softc_chan *ch;
u_int8_t r; u_int8_t r;
int rval; int rval;
rval = 0; rval = 0;
r = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ch = &sc->sc_record;
AUVIA_RECORD_BASE + AUVIA_RP_STAT); r = CH_READ1(sc, ch, AUVIA_RP_STAT);
if (r & AUVIA_RPSTAT_INTR) { if (r & AUVIA_RPSTAT_INTR) {
if (sc->sc_record.sc_intr) if (sc->sc_record.sc_intr)
sc->sc_record.sc_intr(sc->sc_record.sc_arg); sc->sc_record.sc_intr(sc->sc_record.sc_arg);
/* clear interrupts */ /* clear interrupts */
bus_space_write_1(sc->sc_iot, sc->sc_ioh, CH_WRITE1(sc, ch, AUVIA_RP_STAT, AUVIA_RPSTAT_INTR);
AUVIA_RECORD_BASE + AUVIA_RP_STAT, AUVIA_RPSTAT_INTR);
rval = 1; rval = 1;
} }
r = bus_space_read_1(sc->sc_iot, sc->sc_ioh, ch = &sc->sc_play;
AUVIA_PLAY_BASE + AUVIA_RP_STAT); r = CH_READ1(sc, ch, AUVIA_RP_STAT);
if (r & AUVIA_RPSTAT_INTR) { if (r & AUVIA_RPSTAT_INTR) {
if (sc->sc_play.sc_intr) if (sc->sc_play.sc_intr)
sc->sc_play.sc_intr(sc->sc_play.sc_arg); sc->sc_play.sc_intr(sc->sc_play.sc_arg);
/* clear interrupts */ /* clear interrupts */
bus_space_write_1(sc->sc_iot, sc->sc_ioh, CH_WRITE1(sc, ch, AUVIA_RP_STAT, AUVIA_RPSTAT_INTR);
AUVIA_PLAY_BASE + AUVIA_RP_STAT, AUVIA_RPSTAT_INTR);
rval = 1; rval = 1;
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: auviavar.h,v 1.4 2002/10/08 13:10:24 kent Exp $ */ /* $NetBSD: auviavar.h,v 1.5 2002/10/16 15:27:28 kent Exp $ */
/*- /*-
* Copyright (c) 2000 The NetBSD Foundation, Inc. * Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -47,6 +47,7 @@ struct auvia_softc_chan {
struct auvia_dma_op *sc_dma_ops; struct auvia_dma_op *sc_dma_ops;
struct auvia_dma *sc_dma_ops_dma; struct auvia_dma *sc_dma_ops_dma;
u_int16_t sc_dma_op_count; u_int16_t sc_dma_op_count;
int sc_base;
u_int16_t sc_reg; u_int16_t sc_reg;
}; };