Subject: Re: Aureal sound cards support
To: None <current-users@netbsd.org>
From: Pierre Pronchery <khorben@defora.org>
List: current-users
Date: 06/08/2007 02:41:11
This is a multi-part message in MIME format.
--------------070805080502010805040908
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Jared D. McNeill wrote:
> On 6-Jun-07, at 11:14 AM, Pierre Pronchery wrote:
>> first here are the PCI device IDs for two (quite old) sound cards from
>> Aureal.
>>
>> Apparently there is no driver for them. About the process of porting one:
>> - which existing driver would be the most appropriate to start from?
>> (Linux OSS or ALSA, other BSD...)
>
> FreeBSD apparently has a driver:
>
> http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/sound/pci/ -- see
> au88x0.[ch].
>
> NetBSD does not currently support any Aureal hardware.
I got this far:
vortex0 at pci0 dev 12 function 0: Aureal Semiconductor AU8830 Vortex 3D
Digital Audio Processor (audio multimedia, revision 0xfe)
vortex0: interrupting at irq 11
vortex0: ac97: SigmaTel STAC9704 codec; 18 bit DAC, 18 bit ADC, SigmaTel 3D
vortex0: ac97: ext id
ffff<SECONDARY10,SECONDARY01,AC97_23,AC97_22,AMAP,LDAC,SDAC,CDAC,VRM,SPDIF,DRA,VRA>
vortex0: ac97: Slot assignment: 10&11, 3&4, 7&8.
vortex0: Ignore these capabilities.
I get a working mixer, I attached the output of "mixerctl -av" here.
Sound playback still triggers an uvm_fault() though (invalid address 0
in the process accessing the card). Since I am not sure of what I am
doing, I attach the current version of my sources here as well. Please
let me know if you see anything that might help the inclusion of this
driver in -current.
Cheers,
--
khorben
--------------070805080502010805040908
Content-Type: text/plain;
name="mixer.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="mixer.txt"
outputs.master=127,127 volume delta=8
outputs.master.mute=off [ off on ]
outputs.mono=255 volume delta=8
outputs.mono.mute=off [ off on ]
outputs.mono.source=mixerout [ mixerout mic ]
inputs.speaker=255 volume delta=16
inputs.speaker.mute=off [ off on ]
inputs.phone=191 volume delta=8
inputs.phone.mute=on [ off on ]
inputs.mic=191 volume delta=8
inputs.mic.mute=on [ off on ]
inputs.mic.preamp=off [ off on ]
inputs.mic.source=mic0 [ mic0 mic1 ]
inputs.line=191,191 volume delta=8
inputs.line.mute=off [ off on ]
inputs.cd=191,191 volume delta=8
inputs.cd.mute=off [ off on ]
inputs.video=191,191 volume delta=8
inputs.video.mute=off [ off on ]
inputs.aux=191,191 volume delta=8
inputs.aux.mute=off [ off on ]
inputs.dac=191,191 volume delta=8
inputs.dac.mute=off [ off on ]
record.source=mic [ mic cd video aux line mixerout mixeroutmono phone ]
record.volume=0,0 volume delta=16
record.volume.mute=off [ off on ]
outputs.spatial=off [ off on ]
outputs.spatial.center=0 volume delta=16
outputs.spatial.depth=0 volume delta=16
--------------070805080502010805040908
Content-Type: text/plain;
name="vortex.c"
Content-Transfer-Encoding: 8bit
Content-Disposition: inline;
filename="vortex.c"
/* $NetBSD$ */
/* $FreeBSD: /repoman/r/ncvs/src/sys/dev/sound/pci/au88x0.c,v 1.12 2007/04/18 18:26:39 ariff Exp $ */
/*
* Writing: Dag-Erling Coïdan Smørgrav
* Porting: Pierre Pronchery <khorben@defora.org>
*/
/*
* Aureal Vortex cards
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD$");
#include <sys/param.h>
#include <sys/device.h>
#include <sys/audioio.h>
#include <sys/select.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcidevs.h>
#include <dev/audio_if.h>
#include <dev/audiovar.h>
#include <dev/auconv.h>
#include <dev/ic/ac97reg.h>
#include <dev/ic/ac97var.h>
#include <dev/pci/vortexreg.h>
#include <dev/pci/vortexvar.h>
#define PCI_CBIO 0x10
static struct vortex_chipset vortex_chipsets[] = {
{
.voc_audev = {"Vortex","","vortex"},
.voc_pa_id = PCI_PRODUCT_AUREAL_AU8820,
.voc_control = 0x1280c,
.voc_irq_source = 0x12800,
.voc_irq_mask = 0x12804,
.voc_irq_control = 0x12808,
.voc_irq_status = 0x1199c,
.voc_dma_control = 0x1060c,
.voc_fifo_size = 0x20,
.voc_wt_fifos = 32,
.voc_wt_fifo_base = 0x0e800,
.voc_wt_fifo_ctl = 0x0f800,
.voc_wt_dma_ctl = 0x10500,
.voc_adb_fifos = 16,
.voc_adb_fifo_base = 0x0e000,
.voc_adb_fifo_ctl = 0x0f840,
.voc_adb_dma_ctl = 0x10580,
.voc_adb_route_base = 0x10800,
.voc_adb_route_bits = 7,
.voc_adb_codec_in = 0x48,
.voc_adb_codec_out = 0x58
},
{
.voc_audev = {"Vortex 3D","","vortex"},
.voc_pa_id = PCI_PRODUCT_AUREAL_AU8830,
.voc_control = 0x2a00c,
.voc_irq_source = 0x2a000,
.voc_irq_mask = 0x2a004,
.voc_irq_control = 0x2a008,
.voc_irq_status = 0x2919c,
.voc_dma_control = 0x27ae8,
.voc_fifo_size = 0x40,
.voc_wt_fifos = 64,
.voc_wt_fifo_base = 0x10000,
.voc_wt_fifo_ctl = 0x16000,
.voc_wt_dma_ctl = 0x27900,
.voc_adb_fifos = 32,
.voc_adb_fifo_base = 0x14000,
.voc_adb_fifo_ctl = 0x16100,
.voc_adb_dma_ctl = 0x27a00,
.voc_adb_route_base = 0x28000,
.voc_adb_route_bits = 8,
.voc_adb_codec_in = 0x70,
.voc_adb_codec_out = 0x88
},
{
.voc_audev = {"Vortex","","vortex"},
.voc_pa_id = PCI_PRODUCT_AUREAL_AU8810,
.voc_control = 0x2a00c,
.voc_irq_source = 0x2a000,
.voc_irq_mask = 0x2a004,
.voc_irq_control = 0x2a008,
.voc_irq_status = 0x2919c,
.voc_dma_control = 0x27ae8,
.voc_fifo_size = 0x20,
.voc_wt_fifos = 32,
.voc_wt_fifo_base = 0x10000,
.voc_wt_fifo_ctl = 0x16000,
.voc_wt_dma_ctl = 0x27fd8,
.voc_adb_fifos = 16,
.voc_adb_fifo_base = 0x14000,
.voc_adb_fifo_ctl = 0x16100,
.voc_adb_dma_ctl = 0x27180,
.voc_adb_route_base = 0x28000,
.voc_adb_route_bits = 8,
.voc_adb_codec_in = 0x70,
.voc_adb_codec_out = 0x88
},
{
.voc_pa_id = 0
}
};
/* autoconf */
static int vortex_match(struct device *, struct cfdata *, void *);
static void vortex_attach(struct device *, struct device *, void *);
static int vortex_detach(struct device *, int);
/* init & shutdown */
static void vortex_init(struct vortex_softc *);
/* interrupt handler */
static int vortex_intr(void *);
/* ac97 interface callbacks */
static int vortex_ac97_attach(void *, struct ac97_codec_if *);
static int vortex_ac97_read(void *, uint8_t, uint16_t *);
static int vortex_ac97_write(void *, uint8_t, uint16_t);
/* autoconfig */
CFATTACH_DECL(vortex, sizeof(struct vortex_softc),
vortex_match, vortex_attach, vortex_detach, NULL);
static int vortex_query_encoding(void *, struct audio_encoding *);
static int vortex_set_params(void *, int, int, audio_params_t *,
audio_params_t *, stream_filter_list_t *,
stream_filter_list_t *);
static int vortex_getdev(void *, struct audio_device *);
static int vortex_set_port(void *, mixer_ctrl_t *);
static int vortex_get_port(void *, mixer_ctrl_t *);
static int vortex_query_devinfo(void *, mixer_devinfo_t *);
static int vortex_get_props(void *);
static const struct audio_hw_if vortex_hw_if = {
NULL, /* open */
NULL, /* close */
NULL, /* drain */
vortex_query_encoding,
vortex_set_params,
NULL, /* round_blocksize */
NULL, /* commit_settings */
NULL, /* init_output */
NULL, /* init_input */
NULL, /* start_output */
NULL, /* start_input */
NULL, /* halt_output */
NULL, /* halt_input */
NULL, /* speaker_ctl */
vortex_getdev,
NULL, /* setfd */
vortex_set_port,
vortex_get_port,
vortex_query_devinfo,
NULL, /* allocm */
NULL, /* freem */
NULL, /* round_buffersize */
NULL, /* mappage */
vortex_get_props,
NULL, /* trigger_output */
NULL, /* trigger_input */
NULL, /* dev_ioctl */
NULL, /* powerstate */
};
#define VORTEX_NFORMATS 4
static const struct audio_format vortex_formats[VORTEX_NFORMATS] = {
{NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16,
2, AUFMT_STEREO, 0, {4000, 48000}},
{NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16,
1, AUFMT_MONAURAL, 0, {4000, 48000}},
{NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR_LE, 8, 8,
2, AUFMT_STEREO, 0, {4000, 48000}},
{NULL, AUMODE_PLAY | AUMODE_RECORD, AUDIO_ENCODING_ULINEAR_LE, 8, 8,
1, AUFMT_MONAURAL, 0, {4000, 48000}},
};
#define vortex_read(sc, reg, n) \
bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg);
#define vortex_write(sc, reg, data, n) \
bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, data)
/*
* autoconf device callbacks: attach and detach
*/
static void
vortex_pci_shutdown(struct vortex_softc *sc)
{
if (sc->sc_ih != NULL)
pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
if (sc->sc_ios)
bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
}
static int
vortex_match(struct device *parent, struct cfdata *match,
void *aux)
{
struct pci_attach_args *pa;
pa = aux;
if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_AUREAL)
return 0;
switch (PCI_PRODUCT(pa->pa_id)) {
case PCI_PRODUCT_AUREAL_AU8810:
case PCI_PRODUCT_AUREAL_AU8820:
case PCI_PRODUCT_AUREAL_AU8830:
return 1;
default:
return 0;
}
}
static void
vortex_attach(struct device *parent, struct device *self, void *aux)
{
struct vortex_softc *sc;
struct pci_attach_args *pa;
pcireg_t v;
struct vortex_chipset *voc;
char devinfo[256];
pci_intr_handle_t ih;
const char *intrstr;
sc = (struct vortex_softc *)self;
pa = aux;
aprint_naive(": Audio controller\n");
/* model-specific parameters */
v = PCI_PRODUCT(pa->pa_id);
for (voc = vortex_chipsets; voc->voc_pa_id; ++voc)
if (voc->voc_pa_id == v) {
sc->sc_voc = voc;
break;
}
#ifdef DIAGNOSTIC
if (voc->voc_pa_id == 0)
{
aprint_error(": unknown variant");
return;
}
#endif
/* enable the device */
v = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
v | PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE
| PCI_COMMAND_MASTER_ENABLE);
/* map i/o register */
v = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
if (v & PCI_COMMAND_MEM_ENABLE) {
if (pci_mapreg_map(pa, PCI_CBIO, PCI_MAPREG_TYPE_MEM, 0,
&(sc->sc_iot), &(sc->sc_ioh),
&(sc->sc_iob), &(sc->sc_ios))) {
aprint_error("%s: couldn't map i/o space\n",
sc->sc_dev.dv_xname);
return;
}
}
pci_devinfo(pa->pa_id, pa->pa_class, 1, devinfo, sizeof(devinfo));
aprint_normal(": %s\n", devinfo);
/* initialize softc */
sc->sc_pc = pa->pa_pc;
sc->sc_dmat = pa->pa_dmat;
/* map and establish the interrupt */
if (pci_intr_map(pa, &ih)) {
aprint_error("%s: couldn't map interrupt\n",
sc->sc_dev.dv_xname);
return;
}
intrstr = pci_intr_string(pa->pa_pc, ih);
sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_AUDIO, vortex_intr,
sc);
if (sc->sc_ih == NULL) {
aprint_error("%s: couldn't establish interrupt\n",
sc->sc_dev.dv_xname);
if (intrstr != NULL)
aprint_normal(" at %s", intrstr);
aprint_normal("\n");
return;
}
aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
/* FIXME DMA mapping, is it already done? */
/* initialize the hardware */
vortex_init(sc);
/* initialize the ac97 codec and mixer */
sc->host_if.arg = sc;
sc->host_if.attach = vortex_ac97_attach;
sc->host_if.read = vortex_ac97_read;
sc->host_if.write = vortex_ac97_write;
sc->host_if.reset = NULL;
sc->host_if.flags = NULL;
if (ac97_attach(&sc->host_if, self)) {
vortex_pci_shutdown(sc);
return;
}
/* attach audio */
if ((sc->sc_audev = audio_attach_mi(&vortex_hw_if, sc, self)) == NULL) {
vortex_pci_shutdown(sc);
return;
}
}
static int
vortex_detach(struct device *self, int flags)
{
struct vortex_softc *sc;
int res;
sc = (struct vortex_softc *)self;
if (sc->sc_audev != NULL) { /* Test in case audio didn't attach */
res = config_detach(sc->sc_audev, 0);
if (res)
return res;
}
vortex_pci_shutdown(sc);
return 0;
}
static int
vortex_intr(void *p)
{
struct vortex_softc *sc;
struct vortex_chipset *voc;
int pending, source;
sc = p;
voc = sc->sc_voc;
pending = vortex_read(sc, voc->voc_irq_control, 4);
if ((pending & VORTEX_IRQ_PENDING_BIT) == 0)
return 0;
source = vortex_read(sc, voc->voc_irq_source, 4);
if (source & VORTEX_IRQ_FATAL_ERR)
aprint_error("%s: fatal error interrupt received\n",
sc->sc_dev.dv_xname);
if (source & VORTEX_IRQ_PARITY_ERR)
aprint_error("%s: parity error interrupt received\n",
sc->sc_dev.dv_xname);
/* XXX handle the others... */
/* acknowledge the interrupts we just handled */
vortex_write(sc, voc->voc_irq_source, source, 4);
vortex_read(sc, voc->voc_irq_source, 4);
return 1;
}
/* init and shutdown */
static void
vortex_codec_init(struct vortex_softc *sc)
{
uint32_t data;
int i;
/* wave that chicken */
vortex_write(sc, VORTEX_CODEC_CONTROL, 0x8068, 4);
DELAY(VORTEX_SETTLE_DELAY);
vortex_write(sc, VORTEX_CODEC_CONTROL, 0x00e8, 4);
DELAY(1000);
for (i = 0; i < 32; ++i) {
vortex_write(sc, VORTEX_CODEC_CHANNEL + i * 4, 0, 4);
DELAY(VORTEX_SETTLE_DELAY);
}
vortex_write(sc, VORTEX_CODEC_CONTROL, 0x00e8, 4);
DELAY(VORTEX_SETTLE_DELAY);
/* enable both codec channels */
data = vortex_read(sc, VORTEX_CODEC_ENABLE, 4);
data |= (1 << (8 + 0)) | (1 << (8 + 1));
vortex_write(sc, VORTEX_CODEC_ENABLE, data, 4);
DELAY(VORTEX_SETTLE_DELAY);
}
static void
vortex_fifo_init(struct vortex_softc *sc)
{
struct vortex_chipset *voc = sc->sc_voc;
int i;
/* reset, then clear the ADB FIFOs */
for (i = 0; i < voc->voc_adb_fifos; ++i)
vortex_write(sc, voc->voc_adb_fifo_ctl + i * 4, 0x42000, 4);
/* XXX could it be optimized? */
for (i = 0; i < voc->voc_adb_fifos * voc->voc_fifo_size; ++i)
vortex_write(sc, voc->voc_adb_fifo_base + i * 4, 0, 4);
/* reset, then clear the WT FIFOs */
for (i = 0; i < voc->voc_wt_fifos; ++i)
vortex_write(sc, voc->voc_wt_fifo_ctl + i * 4, 0x42000, 4);
for (i = 0; i < voc->voc_wt_fifos * voc->voc_fifo_size; ++i)
vortex_write(sc, voc->voc_wt_fifo_base + i * 4, 0, 4);
}
static void
vortex_init(struct vortex_softc *sc)
{
struct vortex_chipset *voc = sc->sc_voc;
/* reset the chip */
vortex_write(sc, voc->voc_control, 0xffffffff, 4);
DELAY(10000);
/* clear all interrupts */
vortex_write(sc, voc->voc_irq_source, 0xffffffff, 4);
vortex_read(sc, voc->voc_irq_source, 4);
vortex_read(sc, voc->voc_irq_status, 4);
/* initialize the codec */
vortex_codec_init(sc);
/* initialize the fifos */
vortex_fifo_init(sc);
/* initialize the DMA engine */
/* XXX chicken-waving! ...?!? */
vortex_write(sc, voc->voc_dma_control, 0x1380000, 4);
}
static int
vortex_ac97_attach(void *arg, struct ac97_codec_if *codec_if)
{
struct vortex_softc *sc;
sc = arg;
sc->codec_if = codec_if;
return 0;
}
static int
vortex_ac97_wait(struct vortex_softc *sc)
{
uint32_t data;
int i;
for (i = 0; i < VORTEX_RETRY_COUNT; ++i) {
data = vortex_read(sc, VORTEX_CODEC_CONTROL, 4);
if (data & VORTEX_CDCTL_WROK)
return (0);
DELAY(VORTEX_SETTLE_DELAY);
}
aprint_error("%s: timeout while waiting for codec\n",
sc->sc_dev.dv_xname);
return -1;
}
static int
vortex_ac97_read(void *arg, uint8_t reg, uint16_t * val)
{
struct vortex_softc * sc;
uint32_t data;
int s;
sc = arg;
s = splaudio();
vortex_ac97_wait(sc);
vortex_write(sc, VORTEX_CODEC_IO, VORTEX_CDIO_READ(reg), 4);
DELAY(1000);
data = vortex_read(sc, VORTEX_CODEC_IO, 4);
splx(s);
*val = (data & VORTEX_CDIO_DATA_MASK) >> VORTEX_CDIO_DATA_SHIFT;
return 0;
}
static int
vortex_ac97_write(void *arg, uint8_t reg, uint16_t val)
{
struct vortex_softc * sc;
int s;
sc = arg;
s = splaudio();
vortex_ac97_wait(sc);
vortex_write(sc, VORTEX_CODEC_IO, VORTEX_CDIO_WRITE(reg, val), 4);
splx(s);
return 0;
}
static int
vortex_getdev(void *addr, struct audio_device *dev)
{
struct vortex_softc *sc;
sc = addr;
*dev = sc->sc_voc->voc_audev;
return 0;
}
static int
vortex_set_port(void *addr, mixer_ctrl_t *mctl)
{
struct vortex_softc * sc;
sc = addr;
return sc->codec_if->vtbl->mixer_set_port(sc->codec_if, mctl);
}
static int
vortex_get_port(void *addr, mixer_ctrl_t *mctl)
{
struct vortex_softc * sc;
sc = addr;
return sc->codec_if->vtbl->mixer_get_port(sc->codec_if, mctl);
}
static int
vortex_query_devinfo(void *hdl, mixer_devinfo_t *di)
{
struct vortex_softc * sc;
sc = hdl;
return sc->codec_if->vtbl->query_devinfo(sc->codec_if, di);
}
static int
vortex_get_props(void * addr)
{
return AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT |
AUDIO_PROP_FULLDUPLEX;
}
static int
vortex_query_encoding(void *addr, struct audio_encoding *fp)
{
struct vortex_softp *sc;
sc = addr;
switch (fp->index) {
case 0:
strcpy(fp->name, AudioEulinear);
fp->encoding = AUDIO_ENCODING_ULINEAR;
fp->precision = 8;
fp->flags = 0;
break;
case 1:
strcpy(fp->name, AudioEmulaw);
fp->encoding = AUDIO_ENCODING_ULAW;
fp->precision = 8;
fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
break;
case 2:
strcpy(fp->name, AudioEalaw);
fp->encoding = AUDIO_ENCODING_ALAW;
fp->precision = 8;
fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
break;
case 3:
strcpy(fp->name, AudioEslinear);
fp->encoding = AUDIO_ENCODING_SLINEAR;
fp->precision = 8;
fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
break;
case 4:
strcpy(fp->name, AudioEslinear_le);
fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
fp->precision = 16;
fp->flags = 0;
break;
case 5:
strcpy(fp->name, AudioEulinear_le);
fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
fp->precision = 16;
fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
break;
case 6:
strcpy(fp->name, AudioEslinear_be);
fp->encoding = AUDIO_ENCODING_SLINEAR_BE;
fp->precision = 16;
fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
break;
case 7:
strcpy(fp->name, AudioEulinear_be);
fp->encoding = AUDIO_ENCODING_ULINEAR_BE;
fp->precision = 16;
fp->flags = AUDIO_ENCODINGFLAG_EMULATED;
break;
default:
return EINVAL;
}
return 0;
}
static int
vortex_set_params(void *addr, int setmode, int usemode,
audio_params_t *play, audio_params_t *rec,
stream_filter_list_t *pfil, stream_filter_list_t *rfil)
{
struct vortex_softc *sc;
struct audio_params *p;
stream_filter_list_t *fil;
int mode;
int index;
sc = addr;
for (mode = AUMODE_RECORD; mode != -1;
mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
if ((setmode & mode) == 0)
continue;
if (mode == AUMODE_PLAY) {
p = play;
fil = pfil;
} else {
p = rec;
fil = rfil;
}
if (p->sample_rate < 4000 || p->sample_rate > 48000 ||
(p->precision != 8 && p->precision != 16))
return EINVAL;
index = auconv_set_converter(vortex_formats, VORTEX_NFORMATS,
mode, p, FALSE, fil);
if (index < 0)
return EINVAL;
}
/* set speed */
/* XXX */
return 0;
}
--------------070805080502010805040908
Content-Type: text/plain;
name="vortexreg.h"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="vortexreg.h"
/* $NetBSD$ */
#ifndef _DEV_PCI_VORTEXREG_H_
#define _DEV_PCI_VORTEXREG_H_
/*
* Common parameters
*/
#define VORTEX_SETTLE_DELAY 1000
#define VORTEX_RETRY_COUNT 10
#define VORTEX_BUFSIZE_MIN 0x1000
#define VORTEX_BUFSIZE_DFLT 0x4000
#define VORTEX_BUFSIZE_MAX 0x4000
/*
* Codec control registers
*
* VORTEX_CODEC_CHANNEL array of 32 32-bits words
*
* VORTEX_CODEC_CONTROL control register
*
* bit 16 ready
*
* VORTEX_CODEC_IO I/O register
*
* bits 0-15 contents of codec register
* bits 16-22 address of codec register
* bit 23 0 for read, 1 for write
*/
#define VORTEX_CODEC_CHANNEL 0x29080
#define VORTEX_CODEC_CONTROL 0x29184
#define VORTEX_CDCTL_WROK 0x00000100
#define VORTEX_CODEC_IO 0x29188
#define VORTEX_CDIO_DATA_SHIFT 0
#define VORTEX_CDIO_DATA_MASK 0x0000ffff
#define VORTEX_CDIO_ADDR_SHIFT 16
#define VORTEX_CDIO_ADDR_MASK 0x007f0000
#define VORTEX_CDIO_RDBIT 0x00000000
#define VORTEX_CDIO_WRBIT 0x00800000
#define VORTEX_CDIO_READ(a) (VORTEX_CDIO_RDBIT | \
(((a) << VORTEX_CDIO_ADDR_SHIFT) & VORTEX_CDIO_ADDR_MASK))
#define VORTEX_CDIO_WRITE(a, d) (VORTEX_CDIO_WRBIT | \
(((a) << VORTEX_CDIO_ADDR_SHIFT) & VORTEX_CDIO_ADDR_MASK) | \
(((d) << VORTEX_CDIO_DATA_SHIFT) & VORTEX_CDIO_DATA_MASK))
#define VORTEX_CODEC_ENABLE 0x29190
#endif /* !_DEV_PCI_VORTEXREG_H_ */
--------------070805080502010805040908
Content-Type: text/plain;
name="vortexvar.h"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="vortexvar.h"
/* $NetBSD$ */
#ifndef _DEV_PCI_VORTEXVAR_H_
#define _DEV_PCI_VORTEXVAR_H_
struct vortex_chipset {
struct audio_device voc_audev;
pcireg_t voc_pa_id;
/* General control register */
uint32_t voc_control;
#define VORTEX_CTL_MIDI_ENABLE 0x0001
#define VORTEX_CTL_GAME_ENABLE 0x0008
#define VORTEX_CLT_IRQ_ENABLE 0x4000
/* IRQ control register */
uint32_t voc_irq_source;
#define VORTEX_IRQ_FATAL_ERR 0x0001
#define VORTEX_IRQ_PARITY_ERR 0x0002
#define VORTEX_IRQ_REG_ERR 0x0004
#define VORTEX_IRQ_FIFO_ERR 0x0008
#define VORTEX_IRQ_DMA_ERR 0x0010
#define VORTEX_IRQ_PCMOUT 0x0020
#define VORTEX_IRQ_TIMER 0x1000
#define VORTEX_IRQ_MIDI 0x2000
#define VORTEX_IRQ_MODEM 0x4000
uint32_t voc_irq_mask;
uint32_t voc_irq_control;
#define VORTEX_IRQ_PENDING_BIT 0x0001
uint32_t voc_irq_status;
/* DMA control registers */
uint32_t voc_dma_control;
/* FIFOs */
int voc_fifo_size;
int voc_wt_fifos;
uint32_t voc_wt_fifo_base;
uint32_t voc_wt_fifo_ctl;
uint32_t voc_wt_dma_ctl;
int voc_adb_fifos;
uint32_t voc_adb_fifo_base;
uint32_t voc_adb_fifo_ctl;
uint32_t voc_adb_dma_ctl;
/* Routing */
uint32_t voc_adb_route_base;
int voc_adb_route_bits;
int voc_adb_codec_in;
int voc_adb_codec_out;
};
struct vortex_softc {
struct device sc_dev;
audio_device_t sc_audv;
/* autoconfig parameters */
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
bus_addr_t sc_iob;
bus_size_t sc_ios;
pci_chipset_tag_t sc_pc; /* PCI tag */
bus_dma_tag_t sc_dmat;
void *sc_ih; /* interrupt handler */
/* vortex device structures */
struct device *sc_audev;
struct vortex_chipset *sc_voc;
struct ac97_host_if host_if;
struct ac97_codec_if *codec_if;
};
#endif /* !_DEV_PCI_VORTEXVAR_H_ */
--------------070805080502010805040908--