A couple of months' worth of back-burner hacking: restructure to better
handle the minor (but significant) differences between the various Vortex chips; add (incomplete) support for playback.
This commit is contained in:
parent
efae2cbb66
commit
7526d14d48
@ -37,6 +37,103 @@
|
||||
#include <dev/pci/pcireg.h>
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
|
||||
/***************************************************************************\
|
||||
* *
|
||||
* SUPPORTED CHIPSETS *
|
||||
* *
|
||||
\***************************************************************************/
|
||||
|
||||
static struct au88x0_chipset au88x0_chipsets[] = {
|
||||
{
|
||||
.auc_name = "Aureal Vortex (8820)",
|
||||
.auc_pci_id = 0x000112eb,
|
||||
|
||||
.auc_control = 0x1280c,
|
||||
|
||||
.auc_irq_source = 0x12800,
|
||||
.auc_irq_mask = 0x12804,
|
||||
.auc_irq_control = 0x12808,
|
||||
.auc_irq_status = 0x1199c,
|
||||
|
||||
.auc_dma_control = 0x1060c,
|
||||
|
||||
.auc_fifo_size = 0x20,
|
||||
.auc_wt_fifos = 32,
|
||||
.auc_wt_fifo_base = 0x0e800,
|
||||
.auc_wt_fifo_ctl = 0x0f800,
|
||||
.auc_wt_dma_ctl = 0x10500,
|
||||
.auc_adb_fifos = 16,
|
||||
.auc_adb_fifo_base = 0x0e000,
|
||||
.auc_adb_fifo_ctl = 0x0f840,
|
||||
.auc_adb_dma_ctl = 0x10580,
|
||||
|
||||
.auc_adb_route_base = 0x10800,
|
||||
.auc_adb_route_bits = 7,
|
||||
.auc_adb_codec_in = 0x48,
|
||||
.auc_adb_codec_out = 0x58,
|
||||
},
|
||||
{
|
||||
.auc_name = "Aureal Vortex 2 (8830)",
|
||||
.auc_pci_id = 0x000212eb,
|
||||
|
||||
.auc_control = 0x2a00c,
|
||||
|
||||
.auc_irq_source = 0x2a000,
|
||||
.auc_irq_mask = 0x2a004,
|
||||
.auc_irq_control = 0x2a008,
|
||||
.auc_irq_status = 0x2919c,
|
||||
|
||||
.auc_dma_control = 0x27ae8,
|
||||
|
||||
.auc_fifo_size = 0x40,
|
||||
.auc_wt_fifos = 64,
|
||||
.auc_wt_fifo_base = 0x10000,
|
||||
.auc_wt_fifo_ctl = 0x16000,
|
||||
.auc_wt_dma_ctl = 0x27900,
|
||||
.auc_adb_fifos = 32,
|
||||
.auc_adb_fifo_base = 0x14000,
|
||||
.auc_adb_fifo_ctl = 0x16100,
|
||||
.auc_adb_dma_ctl = 0x27a00,
|
||||
|
||||
.auc_adb_route_base = 0x28000,
|
||||
.auc_adb_route_bits = 8,
|
||||
.auc_adb_codec_in = 0x70,
|
||||
.auc_adb_codec_out = 0x88,
|
||||
},
|
||||
{
|
||||
.auc_name = "Aureal Vortex Advantage (8810)",
|
||||
.auc_pci_id = 0x000312eb,
|
||||
|
||||
.auc_control = 0x2a00c,
|
||||
|
||||
.auc_irq_source = 0x2a000,
|
||||
.auc_irq_mask = 0x2a004,
|
||||
.auc_irq_control = 0x2a008,
|
||||
.auc_irq_status = 0x2919c,
|
||||
|
||||
.auc_dma_control = 0x27ae8,
|
||||
|
||||
.auc_fifo_size = 0x20,
|
||||
.auc_wt_fifos = 32,
|
||||
.auc_wt_fifo_base = 0x10000,
|
||||
.auc_wt_fifo_ctl = 0x16000,
|
||||
.auc_wt_dma_ctl = 0x27fd8,
|
||||
.auc_adb_fifos = 16,
|
||||
.auc_adb_fifo_base = 0x14000,
|
||||
.auc_adb_fifo_ctl = 0x16100,
|
||||
.auc_adb_dma_ctl = 0x27180,
|
||||
|
||||
.auc_adb_route_base = 0x28000,
|
||||
.auc_adb_route_bits = 8,
|
||||
.auc_adb_codec_in = 0x70,
|
||||
.auc_adb_codec_out = 0x88,
|
||||
},
|
||||
{
|
||||
.auc_pci_id = 0,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************\
|
||||
* *
|
||||
@ -343,12 +440,13 @@ static void
|
||||
au88x0_intr(void *arg)
|
||||
{
|
||||
struct au88x0_info *aui = arg;
|
||||
struct au88x0_chipset *auc = aui->aui_chipset;
|
||||
int pending, source;
|
||||
|
||||
pending = au88x0_read(aui, AU88X0_IRQ_PENDING, 4);
|
||||
pending = au88x0_read(aui, auc->auc_irq_control, 4);
|
||||
if ((pending & AU88X0_IRQ_PENDING_BIT) == 0)
|
||||
return;
|
||||
source = au88x0_read(aui, AU88X0_IRQ_SOURCE, 4);
|
||||
source = au88x0_read(aui, auc->auc_irq_source, 4);
|
||||
if (source & AU88X0_IRQ_FATAL_ERR)
|
||||
device_printf(aui->aui_dev,
|
||||
"fatal error interrupt received\n");
|
||||
@ -358,8 +456,8 @@ au88x0_intr(void *arg)
|
||||
/* XXX handle the others... */
|
||||
|
||||
/* acknowledge the interrupts we just handled */
|
||||
au88x0_write(aui, AU88X0_IRQ_SOURCE, source, 4);
|
||||
au88x0_read(aui, AU88X0_IRQ_SOURCE, 4);
|
||||
au88x0_write(aui, auc->auc_irq_source, source, 4);
|
||||
au88x0_read(aui, auc->auc_irq_source, 4);
|
||||
}
|
||||
|
||||
|
||||
@ -377,19 +475,20 @@ au88x0_intr(void *arg)
|
||||
static void
|
||||
au88x0_fifo_init(struct au88x0_info *aui)
|
||||
{
|
||||
struct au88x0_chipset *auc = aui->aui_chipset;
|
||||
int i;
|
||||
|
||||
/* reset, then clear the ADB FIFOs */
|
||||
for (i = 0; i < AU88X0_ADB_FIFOS; ++i)
|
||||
au88x0_write(aui, AU88X0_ADB_FIFO_CTL + i * 4, 0x42000, 4);
|
||||
for (i = 0; i < AU88X0_ADB_FIFOS * AU88X0_ADB_FIFO_SIZE; ++i)
|
||||
au88x0_write(aui, AU88X0_ADB_FIFO_BASE + i * 4, 0, 4);
|
||||
for (i = 0; i < auc->auc_adb_fifos; ++i)
|
||||
au88x0_write(aui, auc->auc_adb_fifo_ctl + i * 4, 0x42000, 4);
|
||||
for (i = 0; i < auc->auc_adb_fifos * auc->auc_fifo_size; ++i)
|
||||
au88x0_write(aui, auc->auc_adb_fifo_base + i * 4, 0, 4);
|
||||
|
||||
/* reset, then clear the WT FIFOs */
|
||||
for (i = 0; i < AU88X0_WT_FIFOS; ++i)
|
||||
au88x0_write(aui, AU88X0_WT_FIFO_CTL + i * 4, 0x42000, 4);
|
||||
for (i = 0; i < AU88X0_WT_FIFOS * AU88X0_WT_FIFO_SIZE; ++i)
|
||||
au88x0_write(aui, AU88X0_WT_FIFO_BASE + i * 4, 0, 4);
|
||||
for (i = 0; i < auc->auc_wt_fifos; ++i)
|
||||
au88x0_write(aui, auc->auc_wt_fifo_ctl + i * 4, 0x42000, 4);
|
||||
for (i = 0; i < auc->auc_wt_fifos * auc->auc_fifo_size; ++i)
|
||||
au88x0_write(aui, auc->auc_wt_fifo_base + i * 4, 0, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -398,15 +497,16 @@ au88x0_fifo_init(struct au88x0_info *aui)
|
||||
static void
|
||||
au88x0_init(struct au88x0_info *aui)
|
||||
{
|
||||
struct au88x0_chipset *auc = aui->aui_chipset;
|
||||
|
||||
/* reset the chip */
|
||||
au88x0_write(aui, AU88X0_CONTROL, 0xffffffff, 4);
|
||||
au88x0_write(aui, auc->auc_control, 0xffffffff, 4);
|
||||
DELAY(10000);
|
||||
|
||||
/* clear all interrupts */
|
||||
au88x0_write(aui, AU88X0_IRQ_SOURCE, 0xffffffff, 4);
|
||||
au88x0_read(aui, AU88X0_IRQ_SOURCE, 4);
|
||||
au88x0_read(aui, AU88X0_IRQ_STATUS, 4);
|
||||
au88x0_write(aui, auc->auc_irq_source, 0xffffffff, 4);
|
||||
au88x0_read(aui, auc->auc_irq_source, 4);
|
||||
au88x0_read(aui, auc->auc_irq_status, 4);
|
||||
|
||||
/* initialize the codec */
|
||||
au88x0_codec_init(aui);
|
||||
@ -416,7 +516,7 @@ au88x0_init(struct au88x0_info *aui)
|
||||
|
||||
/* initialize the DMA engine */
|
||||
/* XXX chicken-waving! */
|
||||
au88x0_write(aui, AU88X0_DMA_CONTROL, 0x1380000, 4);
|
||||
au88x0_write(aui, auc->auc_dma_control, 0x1380000, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -448,18 +548,17 @@ au88x0_set_status(device_t dev)
|
||||
static int
|
||||
au88x0_pci_probe(device_t dev)
|
||||
{
|
||||
struct au88x0_chipset *auc;
|
||||
uint32_t pci_id;
|
||||
|
||||
switch (pci_get_devid(dev)) {
|
||||
case AUREAL_VORTEX_2:
|
||||
device_set_desc(dev, "Aureal Vortex 2");
|
||||
return (0);
|
||||
case AUREAL_VORTEX_ADVANTAGE:
|
||||
device_set_desc(dev, "Aureal Vortex Advantage");
|
||||
return (0);
|
||||
default:
|
||||
return (ENXIO);
|
||||
pci_id = pci_get_devid(dev);
|
||||
for (auc = au88x0_chipsets; auc->auc_pci_id; ++auc) {
|
||||
if (auc->auc_pci_id == pci_id) {
|
||||
device_set_desc(dev, auc->auc_name);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -468,6 +567,7 @@ au88x0_pci_probe(device_t dev)
|
||||
static int
|
||||
au88x0_pci_attach(device_t dev)
|
||||
{
|
||||
struct au88x0_chipset *auc;
|
||||
struct au88x0_info *aui = NULL;
|
||||
uint32_t config;
|
||||
int error;
|
||||
@ -480,15 +580,11 @@ au88x0_pci_attach(device_t dev)
|
||||
|
||||
/* Model-specific parameters */
|
||||
aui->aui_model = pci_get_devid(dev);
|
||||
switch (aui->aui_model) {
|
||||
case AUREAL_VORTEX_1:
|
||||
break;
|
||||
case AUREAL_VORTEX_2:
|
||||
case AUREAL_VORTEX_ADVANTAGE:
|
||||
break;
|
||||
default:
|
||||
for (auc = au88x0_chipsets; auc->auc_pci_id; ++auc)
|
||||
if (auc->auc_pci_id == aui->aui_model)
|
||||
aui->aui_chipset = auc;
|
||||
if (aui->aui_chipset == NULL)
|
||||
panic("%s() called for non-au88x0 device", __func__);
|
||||
}
|
||||
|
||||
/* enable pio, mmio, bus-mastering dma */
|
||||
config = pci_read_config(dev, PCIR_COMMAND, 2);
|
||||
@ -567,8 +663,8 @@ au88x0_pci_attach(device_t dev)
|
||||
/* register with the pcm driver */
|
||||
if (pcm_register(dev, aui, 0, 0))
|
||||
goto failed;
|
||||
#if 0
|
||||
pcm_addchan(dev, PCMDIR_PLAY, &au88x0_chan_class, aui);
|
||||
#if 0
|
||||
pcm_addchan(dev, PCMDIR_REC, &au88x0_chan_class, aui);
|
||||
#endif
|
||||
au88x0_set_status(dev);
|
||||
|
@ -31,6 +31,56 @@
|
||||
#ifndef _AU88X0_H_INCLUDED
|
||||
#define _AU88X0_H_INCLUDED
|
||||
|
||||
/*
|
||||
* Chipset parameters
|
||||
*/
|
||||
struct au88x0_chipset {
|
||||
const char *auc_name;
|
||||
uint32_t auc_pci_id;
|
||||
|
||||
/* General control register */
|
||||
uint32_t auc_control;
|
||||
#define AU88X0_CTL_MIDI_ENABLE 0x0001
|
||||
#define AU88X0_CTL_GAME_ENABLE 0x0008
|
||||
#define AU88X0_CTL_IRQ_ENABLE 0x4000
|
||||
|
||||
/* IRQ control register */
|
||||
uint32_t auc_irq_source;
|
||||
#define AU88X0_IRQ_FATAL_ERR 0x0001
|
||||
#define AU88X0_IRQ_PARITY_ERR 0x0002
|
||||
#define AU88X0_IRQ_REG_ERR 0x0004
|
||||
#define AU88X0_IRQ_FIFO_ERR 0x0008
|
||||
#define AU88X0_IRQ_DMA_ERR 0x0010
|
||||
#define AU88X0_IRQ_PCMOUT 0x0020
|
||||
#define AU88X0_IRQ_TIMER 0x1000
|
||||
#define AU88X0_IRQ_MIDI 0x2000
|
||||
#define AU88X0_IRQ_MODEM 0x4000
|
||||
uint32_t auc_irq_mask;
|
||||
uint32_t auc_irq_control;
|
||||
#define AU88X0_IRQ_PENDING_BIT 0x0001
|
||||
uint32_t auc_irq_status;
|
||||
|
||||
/* DMA control registers */
|
||||
uint32_t auc_dma_control;
|
||||
|
||||
/* FIFOs */
|
||||
int auc_fifo_size;
|
||||
int auc_wt_fifos;
|
||||
uint32_t auc_wt_fifo_base;
|
||||
uint32_t auc_wt_fifo_ctl;
|
||||
uint32_t auc_wt_dma_ctl;
|
||||
int auc_adb_fifos;
|
||||
uint32_t auc_adb_fifo_base;
|
||||
uint32_t auc_adb_fifo_ctl;
|
||||
uint32_t auc_adb_dma_ctl;
|
||||
|
||||
/* Routing */
|
||||
uint32_t auc_adb_route_base;
|
||||
int auc_adb_route_bits;
|
||||
int auc_adb_codec_in;
|
||||
int auc_adb_codec_out;
|
||||
};
|
||||
|
||||
/*
|
||||
* Channel information
|
||||
*/
|
||||
@ -48,9 +98,16 @@ struct au88x0_info {
|
||||
/* the device we're associated with */
|
||||
device_t aui_dev;
|
||||
uint32_t aui_model;
|
||||
struct au88x0_chipset *aui_chipset;
|
||||
|
||||
/* parameters */
|
||||
bus_size_t aui_bufsize;
|
||||
int aui_wt_fifos;
|
||||
int aui_wt_fifo_ctl;
|
||||
int aui_adb_fifos;
|
||||
int aui_adb_fifo_ctl;
|
||||
int aui_fifo_size;
|
||||
uint32_t aui_chanbase;
|
||||
|
||||
/* bus_space tag and handle */
|
||||
bus_space_tag_t aui_spct;
|
||||
@ -77,13 +134,6 @@ struct au88x0_info {
|
||||
struct au88x0_chan_info aui_chan[2];
|
||||
};
|
||||
|
||||
/*
|
||||
* PCI IDs of supported cards
|
||||
*/
|
||||
#define AUREAL_VORTEX_1 0x000112eb /* 8820 (not supported) */
|
||||
#define AUREAL_VORTEX_2 0x000212eb /* 8830 */
|
||||
#define AUREAL_VORTEX_ADVANTAGE 0x000312eb /* 8810 */
|
||||
|
||||
/*
|
||||
* Common parameters
|
||||
*/
|
||||
@ -93,30 +143,6 @@ struct au88x0_info {
|
||||
#define AU88X0_BUFSIZE_DFLT 0x4000
|
||||
#define AU88X0_BUFSIZE_MAX 0x4000
|
||||
|
||||
/*
|
||||
* General control registers
|
||||
*/
|
||||
#define AU88X0_CONTROL 0x2a00c
|
||||
#define AU88X0_CTL_MIDI_ENABLE 0x0001
|
||||
#define AU88X0_CTL_GAME_ENABLE 0x0008
|
||||
#define AU88X0_CTL_IRQ_ENABLE 0x4000
|
||||
|
||||
#define AU88X0_IRQ_SOURCE 0x2a000
|
||||
#define AU88X0_IRQ_MASK 0x2a004
|
||||
#define AU88X0_IRQ_FATAL_ERR 0x0001
|
||||
#define AU88X0_IRQ_PARITY_ERR 0x0002
|
||||
#define AU88X0_IRQ_REG_ERR 0x0004
|
||||
#define AU88X0_IRQ_FIFO_ERR 0x0008
|
||||
#define AU88X0_IRQ_DMA_ERR 0x0010
|
||||
#define AU88X0_IRQ_PCMOUT 0x0020
|
||||
#define AU88X0_IRQ_TIMER 0x1000
|
||||
#define AU88X0_IRQ_MIDI 0x2000
|
||||
#define AU88X0_IRQ_MODEM 0x4000
|
||||
#define AU88X0_IRQ_PENDING 0x2a008
|
||||
#define AU88X0_IRQ_PENDING_BIT 0x0001
|
||||
#define AU88X0_IRQ_STATUS 0x2919c
|
||||
#define AU88X0_DMA_CONTROL 0x27ae8
|
||||
|
||||
/*
|
||||
* Codec control registers
|
||||
*
|
||||
@ -149,26 +175,4 @@ struct au88x0_info {
|
||||
(((d) << AU88X0_CDIO_DATA_SHIFT) & AU88X0_CDIO_DATA_MASK))
|
||||
#define AU88X0_CODEC_ENABLE 0x29190
|
||||
|
||||
/*
|
||||
* FIFO and DMA contorl registers
|
||||
*
|
||||
* There are two sets of these, one for PCM audio (ADB) and one for
|
||||
* wavetables (WT).
|
||||
*/
|
||||
#define AU88X0_ADB_FIFOS 32
|
||||
#define AU88X0_ADB_FIFO_CTL 0x16100
|
||||
#define AU88X0_ADB_FIFO_BASE 0x14000
|
||||
#define AU88X0_ADB_FIFO_SIZE 0x40
|
||||
#define AU8810_ADB_DMA_CTL 0x27180
|
||||
#define AU8820_ADB_DMA_CTL 0x10580
|
||||
#define AU8830_ADB_DMA_CTL 0x27a00
|
||||
|
||||
#define AU88X0_WT_FIFOS 32
|
||||
#define AU88X0_WT_FIFO_CTL 0x16000
|
||||
#define AU88X0_WT_FIFO_BASE 0x10000
|
||||
#define AU88X0_WT_FIFO_SIZE 0x40
|
||||
#define AU8810_WT_DMA_CTL 0x27fd8
|
||||
#define AU8820_WT_DMA_CTL 0x10500
|
||||
#define AU8830_WT_DMA_CTL 0x27900
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user