Support for 4ch/6ch audio playback with VT8233/VT8235.
This commit is contained in:
parent
706c1ce906
commit
565a6b3384
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue