summaryrefslogtreecommitdiffstats
path: root/sys/dev/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/sound/pci')
-rw-r--r--sys/dev/sound/pci/aureal.c18
-rw-r--r--sys/dev/sound/pci/cmi.c22
-rw-r--r--sys/dev/sound/pci/cs4281.c14
-rw-r--r--sys/dev/sound/pci/csa.c2
-rw-r--r--sys/dev/sound/pci/csapcm.c16
-rw-r--r--sys/dev/sound/pci/ds1.c41
-rw-r--r--sys/dev/sound/pci/emu10k1.c116
-rw-r--r--sys/dev/sound/pci/es137x.c23
-rw-r--r--sys/dev/sound/pci/fm801.c18
-rw-r--r--sys/dev/sound/pci/maestro.c21
-rw-r--r--sys/dev/sound/pci/maestro3.c37
-rw-r--r--sys/dev/sound/pci/neomagic.c17
-rw-r--r--sys/dev/sound/pci/solo.c22
-rw-r--r--sys/dev/sound/pci/t4dwave.c44
-rw-r--r--sys/dev/sound/pci/via82c686.c343
-rw-r--r--sys/dev/sound/pci/vibes.c20
16 files changed, 345 insertions, 429 deletions
diff --git a/sys/dev/sound/pci/aureal.c b/sys/dev/sound/pci/aureal.c
index 09ead9f..419eb98 100644
--- a/sys/dev/sound/pci/aureal.c
+++ b/sys/dev/sound/pci/aureal.c
@@ -44,7 +44,7 @@ static u_int32_t au_playfmt[] = {
AFMT_STEREO | AFMT_S16_LE,
0
};
-static pcmchan_caps au_playcaps = {4000, 48000, au_playfmt, 0};
+static struct pcmchan_caps au_playcaps = {4000, 48000, au_playfmt, 0};
static u_int32_t au_recfmt[] = {
AFMT_U8,
@@ -53,7 +53,7 @@ static u_int32_t au_recfmt[] = {
AFMT_STEREO | AFMT_S16_LE,
0
};
-static pcmchan_caps au_reccaps = {4000, 48000, au_recfmt, 0};
+static struct pcmchan_caps au_reccaps = {4000, 48000, au_recfmt, 0};
/* -------------------------------------------------------------------- */
@@ -61,8 +61,8 @@ struct au_info;
struct au_chinfo {
struct au_info *parent;
- pcm_channel *channel;
- snd_dbuf *buffer;
+ struct pcm_channel *channel;
+ struct snd_dbuf *buffer;
int dir;
};
@@ -73,6 +73,7 @@ struct au_info {
bus_space_handle_t sh[3];
bus_dma_tag_t parent_dmat;
+ void *lock;
u_int32_t x[32], y[128];
char z[128];
@@ -293,7 +294,7 @@ au_prepareoutput(struct au_chinfo *ch, u_int32_t format)
/* -------------------------------------------------------------------- */
/* channel interface */
static void *
-auchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+auchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct au_info *au = devinfo;
struct au_chinfo *ch = (dir == PCMDIR_PLAY)? &au->pch : NULL;
@@ -365,7 +366,7 @@ auchan_getptr(kobj_t obj, void *data)
}
}
-static pcmchan_caps *
+static struct pcmchan_caps *
auchan_getcaps(kobj_t obj, void *data)
{
struct au_chinfo *ch = data;
@@ -620,8 +621,7 @@ au_pci_attach(device_t dev)
irqid = 0;
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
- if (!irq
- || bus_setup_intr(dev, irq, INTR_TYPE_TTY, au_intr, au, &ih)) {
+ if (!irq || snd_setup_intr(dev, irq, 0, au_intr, au, &ih)) {
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
@@ -678,7 +678,7 @@ static device_method_t au_methods[] = {
static driver_t au_driver = {
"pcm",
au_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/cmi.c b/sys/dev/sound/pci/cmi.c
index 27489a2..bb48b70 100644
--- a/sys/dev/sound/pci/cmi.c
+++ b/sys/dev/sound/pci/cmi.c
@@ -83,8 +83,8 @@ struct cmi_info;
struct cmi_chinfo {
struct cmi_info *parent;
- pcm_channel *channel;
- snd_dbuf *buffer;
+ struct pcm_channel *channel;
+ struct snd_dbuf *buffer;
int dir;
int bps; /* bytes per sample */
u_int32_t fmt, spd, phys_buf;
@@ -115,7 +115,7 @@ static u_int32_t cmi_fmt[] = {
0
};
-static pcmchan_caps cmi_caps = {5512, 48000, cmi_fmt, 0};
+static struct pcmchan_caps cmi_caps = {5512, 48000, cmi_fmt, 0};
/* ------------------------------------------------------------------------- */
/* Register Utilities */
@@ -328,7 +328,7 @@ cmi_spdif_speed(struct cmi_info *cmi, int speed) {
/* Channel Interface implementation */
static void *
-cmichan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+cmichan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct cmi_info *cmi = devinfo;
struct cmi_chinfo *ch = (dir == PCMDIR_PLAY) ? &cmi->pch : &cmi->rch;
@@ -541,7 +541,7 @@ cmi_intr(void *data)
return;
}
-static pcmchan_caps *
+static struct pcmchan_caps *
cmichan_getcaps(kobj_t obj, void *data)
{
return &cmi_caps;
@@ -610,7 +610,7 @@ struct sb16props {
#define MIXER_GAIN_REG_RTOL(r) (r - 1)
static int
-cmimix_init(snd_mixer *m)
+cmimix_init(struct snd_mixer *m)
{
struct cmi_info *cmi = mix_getdevinfo(m);
u_int32_t i,v;
@@ -635,7 +635,7 @@ cmimix_init(snd_mixer *m)
}
static int
-cmimix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right)
+cmimix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
{
struct cmi_info *cmi = mix_getdevinfo(m);
u_int32_t r, l, max;
@@ -683,7 +683,7 @@ cmimix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right)
}
static int
-cmimix_setrecsrc(snd_mixer *m, u_int32_t src)
+cmimix_setrecsrc(struct snd_mixer *m, u_int32_t src)
{
struct cmi_info *cmi = mix_getdevinfo(m);
u_int32_t i, ml, sl;
@@ -760,7 +760,7 @@ cmi_probe(device_t dev)
static int
cmi_attach(device_t dev)
{
- snddev_info *d;
+ struct snddev_info *d;
struct cmi_info *cmi;
u_int32_t data;
char status[SND_STATUSLEN];
@@ -793,7 +793,7 @@ cmi_attach(device_t dev)
cmi->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &cmi->irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
if (!cmi->irq ||
- bus_setup_intr(dev, cmi->irq, INTR_TYPE_TTY, cmi_intr, cmi, &cmi->ih)){
+ snd_setup_intr(dev, cmi->irq, 0, cmi_intr, cmi, &cmi->ih)) {
device_printf(dev, "cmi_attach: Unable to map interrupt\n");
goto bad;
}
@@ -877,7 +877,7 @@ static device_method_t cmi_methods[] = {
static driver_t cmi_driver = {
"pcm",
cmi_methods,
- sizeof(snddev_info)
+ sizeof(struct snddev_info)
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/cs4281.c b/sys/dev/sound/pci/cs4281.c
index 2f5f633..506a58a 100644
--- a/sys/dev/sound/pci/cs4281.c
+++ b/sys/dev/sound/pci/cs4281.c
@@ -68,8 +68,8 @@ struct sc_info;
struct sc_chinfo {
struct sc_info *parent;
- snd_dbuf *buffer;
- pcm_channel *channel;
+ struct snd_dbuf *buffer;
+ struct pcm_channel *channel;
u_int32_t spd, fmt, bps, blksz;
@@ -134,7 +134,7 @@ static u_int32_t cs4281_fmts[] = {
0
};
-static pcmchan_caps cs4281_caps = {6024, 48000, cs4281_fmts, 0};
+static struct pcmchan_caps cs4281_caps = {6024, 48000, cs4281_fmts, 0};
/* -------------------------------------------------------------------- */
/* Hardware */
@@ -310,7 +310,7 @@ AC97_DECLARE(cs4281_ac97);
/* shared rec/play channel interface */
static void *
-cs4281chan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+cs4281chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct sc_info *sc = devinfo;
struct sc_chinfo *ch = (dir == PCMDIR_PLAY) ? &sc->pch : &sc->rch;
@@ -437,7 +437,7 @@ cs4281chan_trigger(kobj_t obj, void *data, int go)
return 0;
}
-static pcmchan_caps *
+static struct pcmchan_caps *
cs4281chan_getcaps(kobj_t obj, void *data)
{
return &cs4281_caps;
@@ -810,7 +810,7 @@ cs4281_pci_attach(device_t dev)
goto bad;
}
- if (bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, cs4281_intr, sc, &sc->ih)) {
+ if (snd_setup_intr(dev, sc->irq, 0, cs4281_intr, sc, &sc->ih)) {
device_printf(dev, "unable to setup interrupt\n");
goto bad;
}
@@ -962,7 +962,7 @@ static device_method_t cs4281_methods[] = {
static driver_t cs4281_driver = {
"pcm",
cs4281_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/csa.c b/sys/dev/sound/pci/csa.c
index 8cfc179..9dad2f2 100644
--- a/sys/dev/sound/pci/csa.c
+++ b/sys/dev/sound/pci/csa.c
@@ -155,7 +155,7 @@ csa_attach(device_t dev)
}
/* Enable interrupt. */
- if (bus_setup_intr(dev, resp->irq, INTR_TYPE_TTY, csa_intr, scp, &scp->ih)) {
+ if (snd_setup_intr(dev, resp->irq, 0, csa_intr, scp, &scp->ih)) {
bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io);
bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem);
bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq);
diff --git a/sys/dev/sound/pci/csapcm.c b/sys/dev/sound/pci/csapcm.c
index 8bad7b5..399ac15 100644
--- a/sys/dev/sound/pci/csapcm.c
+++ b/sys/dev/sound/pci/csapcm.c
@@ -45,8 +45,8 @@ struct csa_info;
struct csa_chinfo {
struct csa_info *parent;
- pcm_channel *channel;
- snd_dbuf *buffer;
+ struct pcm_channel *channel;
+ struct snd_dbuf *buffer;
int dir;
u_int32_t fmt;
int dma;
@@ -93,14 +93,14 @@ static u_int32_t csa_playfmt[] = {
AFMT_STEREO | AFMT_S16_BE,
0
};
-static pcmchan_caps csa_playcaps = {8000, 48000, csa_playfmt, 0};
+static struct pcmchan_caps csa_playcaps = {8000, 48000, csa_playfmt, 0};
static u_int32_t csa_recfmt[] = {
AFMT_S16_LE,
AFMT_STEREO | AFMT_S16_LE,
0
};
-static pcmchan_caps csa_reccaps = {11025, 48000, csa_recfmt, 0};
+static struct pcmchan_caps csa_reccaps = {11025, 48000, csa_recfmt, 0};
/* -------------------------------------------------------------------- */
/* ac97 codec */
@@ -515,7 +515,7 @@ csa_startdsp(csa_res *resp)
/* channel interface */
static void *
-csachan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+csachan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct csa_info *csa = devinfo;
struct csa_chinfo *ch = (dir == PCMDIR_PLAY)? &csa->pch : &csa->rch;
@@ -654,7 +654,7 @@ csachan_getptr(kobj_t obj, void *data)
return (ptr);
}
-static pcmchan_caps *
+static struct pcmchan_caps *
csachan_getcaps(kobj_t obj, void *data)
{
struct csa_chinfo *ch = data;
@@ -854,7 +854,7 @@ pcmcsa_attach(device_t dev)
snprintf(status, SND_STATUSLEN, "at irq %ld", rman_get_start(resp->irq));
/* Enable interrupt. */
- if (bus_setup_intr(dev, resp->irq, INTR_TYPE_TTY, csa_intr, csa, &csa->ih)) {
+ if (snd_setup_intr(dev, resp->irq, 0, csa_intr, csa, &csa->ih)) {
ac97_destroy(codec);
csa_releaseres(csa, dev);
return (ENXIO);
@@ -902,7 +902,7 @@ static device_method_t pcmcsa_methods[] = {
static driver_t pcmcsa_driver = {
"pcm",
pcmcsa_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/ds1.c b/sys/dev/sound/pci/ds1.c
index 64db2b7..1870917 100644
--- a/sys/dev/sound/pci/ds1.c
+++ b/sys/dev/sound/pci/ds1.c
@@ -87,8 +87,8 @@ struct sc_info;
/* channel registers */
struct sc_pchinfo {
int run, spd, dir, fmt;
- snd_dbuf *buffer;
- pcm_channel *channel;
+ struct snd_dbuf *buffer;
+ struct pcm_channel *channel;
volatile struct pbank *lslot, *rslot;
int lsnum, rsnum;
struct sc_info *parent;
@@ -96,8 +96,8 @@ struct sc_pchinfo {
struct sc_rchinfo {
int run, spd, dir, fmt, num;
- snd_dbuf *buffer;
- pcm_channel *channel;
+ struct snd_dbuf *buffer;
+ struct pcm_channel *channel;
volatile struct rbank *slot;
struct sc_info *parent;
};
@@ -116,6 +116,7 @@ struct sc_info {
struct resource *reg, *irq;
int regid, irqid;
void *ih;
+ void *lock;
void *regbase;
u_int32_t *pbase, pbankbase, pbanksize;
@@ -175,7 +176,7 @@ static u_int32_t ds_recfmt[] = {
AFMT_STEREO | AFMT_U16_LE,
0
};
-static pcmchan_caps ds_reccaps = {4000, 48000, ds_recfmt, 0};
+static struct pcmchan_caps ds_reccaps = {4000, 48000, ds_recfmt, 0};
static u_int32_t ds_playfmt[] = {
AFMT_U8,
@@ -184,7 +185,7 @@ static u_int32_t ds_playfmt[] = {
AFMT_STEREO | AFMT_S16_LE,
0
};
-static pcmchan_caps ds_playcaps = {4000, 96000, ds_playfmt, 0};
+static struct pcmchan_caps ds_playcaps = {4000, 96000, ds_playfmt, 0};
/* -------------------------------------------------------------------- */
/* Hardware */
@@ -473,7 +474,7 @@ ds_setuprch(struct sc_rchinfo *ch)
/* -------------------------------------------------------------------- */
/* play channel interface */
static void *
-ds1pchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+ds1pchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct sc_info *sc = devinfo;
struct sc_pchinfo *ch;
@@ -550,7 +551,9 @@ ds1pchan_trigger(kobj_t obj, void *data, int go)
ds_setuppch(ch);
ds_enapslot(sc, ch->lsnum, 1);
ds_enapslot(sc, ch->rsnum, stereo);
+ snd_mtxlock(sc->lock);
ds_wr(sc, YDSXGR_MODE, 0x00000003, 4);
+ snd_mtxunlock(sc->lock);
} else {
ch->run = 0;
/* ds_setuppch(ch); */
@@ -580,7 +583,7 @@ ds1pchan_getptr(kobj_t obj, void *data)
return ptr;
}
-static pcmchan_caps *
+static struct pcmchan_caps *
ds1pchan_getcaps(kobj_t obj, void *data)
{
return &ds_playcaps;
@@ -601,7 +604,7 @@ CHANNEL_DECLARE(ds1pchan);
/* -------------------------------------------------------------------- */
/* record channel interface */
static void *
-ds1rchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+ds1rchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct sc_info *sc = devinfo;
struct sc_rchinfo *ch;
@@ -672,15 +675,19 @@ ds1rchan_trigger(kobj_t obj, void *data, int go)
if (go == PCMTRIG_START) {
ch->run = 1;
ds_setuprch(ch);
+ snd_mtxlock(sc->lock);
x = ds_rd(sc, YDSXGR_MAPOFREC, 4);
x |= (ch->num == DS1_RECPRIMARY)? 0x02 : 0x01;
ds_wr(sc, YDSXGR_MAPOFREC, x, 4);
ds_wr(sc, YDSXGR_MODE, 0x00000003, 4);
+ snd_mtxunlock(sc->lock);
} else {
ch->run = 0;
+ snd_mtxlock(sc->lock);
x = ds_rd(sc, YDSXGR_MAPOFREC, 4);
x &= ~((ch->num == DS1_RECPRIMARY)? 0x02 : 0x01);
ds_wr(sc, YDSXGR_MAPOFREC, x, 4);
+ snd_mtxunlock(sc->lock);
}
return 0;
@@ -695,7 +702,7 @@ ds1rchan_getptr(kobj_t obj, void *data)
return ch->slot[sc->currbank].PgStart;
}
-static pcmchan_caps *
+static struct pcmchan_caps *
ds1rchan_getcaps(kobj_t obj, void *data)
{
return &ds_reccaps;
@@ -721,6 +728,7 @@ ds_intr(void *p)
struct sc_info *sc = (struct sc_info *)p;
u_int32_t i, x;
+ snd_mtxlock(sc->lock);
i = ds_rd(sc, YDSXGR_STATUS, 4);
if (i & 0x00008000)
device_printf(sc->dev, "timeout irq\n");
@@ -746,6 +754,7 @@ ds_intr(void *p)
ds_wr(sc, YDSXGR_MODE, i | 0x00000002, 4);
}
+ snd_mtxunlock(sc->lock);
}
/* -------------------------------------------------------------------- */
@@ -922,12 +931,12 @@ ds_pci_attach(device_t dev)
struct ac97_info *codec = NULL;
char status[SND_STATUSLEN];
- if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) {
+ if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO)) == NULL) {
device_printf(dev, "cannot allocate softc\n");
return ENXIO;
}
- bzero(sc, sizeof(*sc));
+ sc->lock = snd_mtxcreate(device_get_nameunit(dev));
sc->dev = dev;
subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev);
sc->type = ds_finddev(pci_get_devid(dev), subdev);
@@ -973,8 +982,7 @@ ds_pci_attach(device_t dev)
sc->irqid = 0;
sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
- if (!sc->irq ||
- bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ds_intr, sc, &sc->ih)) {
+ if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, ds_intr, sc, &sc->ih)) {
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
@@ -1003,6 +1011,8 @@ bad:
bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
if (sc->parent_dmat)
bus_dma_tag_destroy(sc->parent_dmat);
+ if (sc->lock)
+ snd_mtxfree(sc->lock);
free(sc, M_DEVBUF);
return ENXIO;
}
@@ -1041,6 +1051,7 @@ ds_pci_detach(device_t dev)
bus_teardown_intr(dev, sc->irq, sc->ih);
bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
bus_dma_tag_destroy(sc->parent_dmat);
+ snd_mtxfree(sc->lock);
free(sc, M_DEVBUF);
return 0;
}
@@ -1057,7 +1068,7 @@ static device_method_t ds1_methods[] = {
static driver_t ds1_driver = {
"pcm",
ds1_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/emu10k1.c b/sys/dev/sound/pci/emu10k1.c
index e816572..388a8e7 100644
--- a/sys/dev/sound/pci/emu10k1.c
+++ b/sys/dev/sound/pci/emu10k1.c
@@ -61,7 +61,7 @@ struct emu_voice {
int start, end, vol;
u_int32_t buf;
struct emu_voice *slave;
- pcm_channel *channel;
+ struct pcm_channel *channel;
};
struct sc_info;
@@ -70,16 +70,16 @@ struct sc_info;
struct sc_pchinfo {
int spd, fmt, blksz, run;
struct emu_voice *master, *slave;
- snd_dbuf *buffer;
- pcm_channel *channel;
+ struct snd_dbuf *buffer;
+ struct pcm_channel *channel;
struct sc_info *parent;
};
struct sc_rchinfo {
int spd, fmt, run, blksz, num;
u_int32_t idxreg, basereg, sizereg, setupreg, irqmask;
- snd_dbuf *buffer;
- pcm_channel *channel;
+ struct snd_dbuf *buffer;
+ struct pcm_channel *channel;
struct sc_info *parent;
};
@@ -96,6 +96,7 @@ struct sc_info {
struct resource *reg, *irq;
int regtype, regid, irqid;
void *ih;
+ void *lock;
int timer, timerinterval;
int pnum, rnum;
@@ -144,7 +145,7 @@ static u_int32_t emu_rfmt_efx[] = {
0
};
-static pcmchan_caps emu_reccaps[3] = {
+static struct pcmchan_caps emu_reccaps[3] = {
{8000, 48000, emu_rfmt_ac97, 0},
{8000, 8000, emu_rfmt_mic, 0},
{48000, 48000, emu_rfmt_efx, 0},
@@ -158,7 +159,7 @@ static u_int32_t emu_pfmt[] = {
0
};
-static pcmchan_caps emu_playcaps = {4000, 48000, emu_pfmt, 0};
+static struct pcmchan_caps emu_playcaps = {4000, 48000, emu_pfmt, 0};
static int adcspeed[8] = {48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000};
@@ -239,6 +240,7 @@ emu_wrefx(struct sc_info *sc, unsigned int pc, unsigned int data)
/* -------------------------------------------------------------------- */
/* ac97 codec */
+/* no locking needed */
static int
emu_rdcd(kobj_t obj, void *devinfo, int regno)
@@ -267,40 +269,6 @@ static kobj_method_t emu_ac97_methods[] = {
AC97_DECLARE(emu_ac97);
/* -------------------------------------------------------------------- */
-
-#if 0
-/* playback channel interrupts */
-static u_int32_t
-emu_testint(struct sc_info *sc, char channel)
-{
- int reg = (channel & 0x20)? CLIPH : CLIPL;
- channel &= 0x1f;
- reg |= 1 << 24;
- reg |= channel << 16;
- return emu_rdptr(sc, 0, reg);
-}
-
-static void
-emu_clrint(struct sc_info *sc, char channel)
-{
- int reg = (channel & 0x20)? CLIPH : CLIPL;
- channel &= 0x1f;
- reg |= 1 << 24;
- reg |= channel << 16;
- emu_wrptr(sc, 0, reg, 1);
-}
-
-static void
-emu_enaint(struct sc_info *sc, char channel, int enable)
-{
- int reg = (channel & 0x20)? CLIEH : CLIEL;
- channel &= 0x1f;
- reg |= 1 << 24;
- reg |= channel << 16;
- emu_wrptr(sc, 0, reg, enable);
-}
-#endif
-
/* stuff */
static int
emu_settimer(struct sc_info *sc)
@@ -450,15 +418,15 @@ emu_valloc(struct sc_info *sc)
static int
emu_vinit(struct sc_info *sc, struct emu_voice *m, struct emu_voice *s,
- u_int32_t sz, pcm_channel *c)
+ u_int32_t sz, struct snd_dbuf *b)
{
void *buf;
buf = emu_memalloc(sc, sz);
if (buf == NULL)
return -1;
- if (c != NULL)
- sndbuf_setup(&c->buffer, buf, sz);
+ if (b != NULL)
+ sndbuf_setup(b, buf, sz);
m->start = emu_memstart(sc, buf) * EMUPAGESIZE;
m->end = m->start + sz;
m->channel = NULL;
@@ -646,10 +614,11 @@ emu_vdump(struct sc_info *sc, struct emu_voice *v)
/* channel interface */
static void *
-emupchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+emupchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct sc_info *sc = devinfo;
struct sc_pchinfo *ch;
+ void *r;
KASSERT(dir == PCMDIR_PLAY, ("emupchan_init: bad direction"));
ch = &sc->pch[sc->pnum++];
@@ -659,12 +628,13 @@ emupchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
ch->blksz = EMU_BUFFSIZE / 2;
ch->fmt = AFMT_U8;
ch->spd = 8000;
+ snd_mtxlock(sc->lock);
ch->master = emu_valloc(sc);
ch->slave = emu_valloc(sc);
- if (emu_vinit(sc, ch->master, ch->slave, EMU_BUFFSIZE, ch->channel))
- return NULL;
- else
- return ch;
+ r = (emu_vinit(sc, ch->master, ch->slave, EMU_BUFFSIZE, ch->buffer))? NULL : ch;
+ snd_mtxunlock(sc->lock);
+
+ return r;
}
static int
@@ -672,8 +642,13 @@ emupchan_free(kobj_t obj, void *data)
{
struct sc_pchinfo *ch = data;
struct sc_info *sc = ch->parent;
+ int r;
+
+ snd_mtxlock(sc->lock);
+ r = emu_memfree(sc, sndbuf_getbuf(ch->buffer));
+ snd_mtxunlock(sc->lock);
- return emu_memfree(sc, sndbuf_getbuf(ch->buffer));
+ return r;
}
static int
@@ -702,8 +677,10 @@ emupchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
int irqrate, blksz;
ch->blksz = blocksize;
+ snd_mtxlock(sc->lock);
emu_settimer(sc);
irqrate = 48000 / sc->timerinterval;
+ snd_mtxunlock(sc->lock);
blksz = (ch->spd * sndbuf_getbps(ch->buffer)) / irqrate;
return blocksize;
}
@@ -717,6 +694,7 @@ emupchan_trigger(kobj_t obj, void *data, int go)
if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
return 0;
+ snd_mtxlock(sc->lock);
if (go == PCMTRIG_START) {
emu_vsetup(ch);
emu_vwrite(sc, ch->master);
@@ -733,6 +711,7 @@ emupchan_trigger(kobj_t obj, void *data, int go)
}
ch->run = (go == PCMTRIG_START)? 1 : 0;
emu_vtrigger(sc, ch->master, ch->run);
+ snd_mtxunlock(sc->lock);
return 0;
}
@@ -741,11 +720,16 @@ emupchan_getptr(kobj_t obj, void *data)
{
struct sc_pchinfo *ch = data;
struct sc_info *sc = ch->parent;
+ int r;
+
+ snd_mtxlock(sc->lock);
+ r = emu_vpos(sc, ch->master);
+ snd_mtxunlock(sc->lock);
- return emu_vpos(sc, ch->master);
+ return r;
}
-static pcmchan_caps *
+static struct pcmchan_caps *
emupchan_getcaps(kobj_t obj, void *data)
{
return &emu_playcaps;
@@ -766,7 +750,7 @@ CHANNEL_DECLARE(emupchan);
/* channel interface */
static void *
-emurchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+emurchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct sc_info *sc = devinfo;
struct sc_rchinfo *ch;
@@ -809,8 +793,10 @@ emurchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
if (sndbuf_alloc(ch->buffer, sc->parent_dmat, EMU_BUFFSIZE) == -1)
return NULL;
else {
+ snd_mtxlock(sc->lock);
emu_wrptr(sc, 0, ch->basereg, vtophys(sndbuf_getbuf(ch->buffer)));
emu_wrptr(sc, 0, ch->sizereg, 0); /* off */
+ snd_mtxunlock(sc->lock);
return ch;
}
}
@@ -847,8 +833,10 @@ emurchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
int irqrate, blksz;
ch->blksz = blocksize;
+ snd_mtxlock(sc->lock);
emu_settimer(sc);
irqrate = 48000 / sc->timerinterval;
+ snd_mtxunlock(sc->lock);
blksz = (ch->spd * sndbuf_getbps(ch->buffer)) / irqrate;
return blocksize;
}
@@ -861,6 +849,7 @@ emurchan_trigger(kobj_t obj, void *data, int go)
struct sc_info *sc = ch->parent;
u_int32_t val;
+ snd_mtxlock(sc->lock);
switch(go) {
case PCMTRIG_START:
ch->run = 1;
@@ -893,6 +882,7 @@ emurchan_trigger(kobj_t obj, void *data, int go)
default:
break;
}
+ snd_mtxunlock(sc->lock);
return 0;
}
@@ -902,11 +892,16 @@ emurchan_getptr(kobj_t obj, void *data)
{
struct sc_rchinfo *ch = data;
struct sc_info *sc = ch->parent;
+ int r;
+
+ snd_mtxlock(sc->lock);
+ r = emu_rdptr(sc, 0, ch->idxreg) & 0x0000ffff;
+ snd_mtxunlock(sc->lock);
- return emu_rdptr(sc, 0, ch->idxreg) & 0x0000ffff;
+ return r;
}
-static pcmchan_caps *
+static struct pcmchan_caps *
emurchan_getcaps(kobj_t obj, void *data)
{
struct sc_rchinfo *ch = data;
@@ -1421,12 +1416,12 @@ emu_pci_attach(device_t dev)
int i, mapped;
char status[SND_STATUSLEN];
- if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) {
+ if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO)) == NULL) {
device_printf(dev, "cannot allocate softc\n");
return ENXIO;
}
- bzero(sc, sizeof(*sc));
+ sc->lock = snd_mtxcreate(device_get_nameunit(dev));
sc->dev = dev;
sc->type = pci_get_devid(dev);
sc->rev = pci_get_revid(dev);
@@ -1482,8 +1477,7 @@ emu_pci_attach(device_t dev)
sc->irqid = 0;
sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
- if (!sc->irq ||
- bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, emu_intr, sc, &sc->ih)) {
+ if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE, emu_intr, sc, &sc->ih)) {
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
@@ -1508,6 +1502,7 @@ bad:
if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih);
if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
if (sc->parent_dmat) bus_dma_tag_destroy(sc->parent_dmat);
+ if (sc->lock) snd_mtxfree(sc->lock);
free(sc, M_DEVBUF);
return ENXIO;
}
@@ -1530,6 +1525,7 @@ emu_pci_detach(device_t dev)
bus_teardown_intr(dev, sc->irq, sc->ih);
bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
bus_dma_tag_destroy(sc->parent_dmat);
+ snd_mtxfree(sc->lock);
free(sc, M_DEVBUF);
return 0;
@@ -1548,7 +1544,7 @@ static device_method_t emu_methods[] = {
static driver_t emu_driver = {
"pcm",
emu_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c
index 6ea6507..116a0ff 100644
--- a/sys/dev/sound/pci/es137x.c
+++ b/sys/dev/sound/pci/es137x.c
@@ -79,8 +79,8 @@ struct es_info;
struct es_chinfo {
struct es_info *parent;
- pcm_channel *channel;
- snd_dbuf *buffer;
+ struct pcm_channel *channel;
+ struct snd_dbuf *buffer;
int dir, num;
u_int32_t fmt, blksz, bufsz;
};
@@ -122,7 +122,7 @@ static u_int32_t es_playfmt[] = {
AFMT_STEREO | AFMT_S16_LE,
0
};
-static pcmchan_caps es_playcaps = {4000, 48000, es_playfmt, 0};
+static struct pcmchan_caps es_playcaps = {4000, 48000, es_playfmt, 0};
static u_int32_t es_recfmt[] = {
AFMT_U8,
@@ -131,7 +131,7 @@ static u_int32_t es_recfmt[] = {
AFMT_STEREO | AFMT_S16_LE,
0
};
-static pcmchan_caps es_reccaps = {4000, 48000, es_recfmt, 0};
+static struct pcmchan_caps es_reccaps = {4000, 48000, es_recfmt, 0};
static const struct {
unsigned volidx:4;
@@ -157,7 +157,7 @@ static const struct {
/* The es1370 mixer interface */
static int
-es1370_mixinit(snd_mixer *m)
+es1370_mixinit(struct snd_mixer *m)
{
int i;
u_int32_t v;
@@ -174,7 +174,7 @@ es1370_mixinit(snd_mixer *m)
}
static int
-es1370_mixset(snd_mixer *m, unsigned dev, unsigned left, unsigned right)
+es1370_mixset(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
{
int l, r, rl, rr;
@@ -195,7 +195,7 @@ es1370_mixset(snd_mixer *m, unsigned dev, unsigned left, unsigned right)
}
static int
-es1370_mixsetrecsrc(snd_mixer *m, u_int32_t src)
+es1370_mixsetrecsrc(struct snd_mixer *m, u_int32_t src)
{
int i, j = 0;
@@ -245,7 +245,7 @@ es1370_wrcodec(struct es_info *es, u_char i, u_char data)
/* channel interface */
static void *
-eschan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+eschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct es_info *es = devinfo;
struct es_chinfo *ch = (dir == PCMDIR_PLAY)? &es->pch : &es->rch;
@@ -394,7 +394,7 @@ eschan_getptr(kobj_t obj, void *data)
return cnt << 2;
}
-static pcmchan_caps *
+static struct pcmchan_caps *
eschan_getcaps(kobj_t obj, void *data)
{
struct es_chinfo *ch = data;
@@ -818,8 +818,7 @@ es_pci_attach(device_t dev)
es->irqid = 0;
es->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &es->irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
- if (!es->irq
- || bus_setup_intr(dev, es->irq, INTR_TYPE_TTY, es_intr, es, &es->ih)) {
+ if (!es->irq || snd_setup_intr(dev, es->irq, 0, es_intr, es, &es->ih)) {
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
@@ -887,7 +886,7 @@ static device_method_t es_methods[] = {
static driver_t es_driver = {
"pcm",
es_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/fm801.c b/sys/dev/sound/pci/fm801.c
index 48b9940..0584c01 100644
--- a/sys/dev/sound/pci/fm801.c
+++ b/sys/dev/sound/pci/fm801.c
@@ -102,7 +102,7 @@
#define DPRINT if(0) printf
/*
-static int fm801ch_setup(pcm_channel *c);
+static int fm801ch_setup(struct pcm_channel *c);
*/
static u_int32_t fmts[] = {
@@ -113,7 +113,7 @@ static u_int32_t fmts[] = {
0
};
-static pcmchan_caps fm801ch_caps = {
+static struct pcmchan_caps fm801ch_caps = {
4000, 48000,
fmts, 0
};
@@ -122,8 +122,8 @@ struct fm801_info;
struct fm801_chinfo {
struct fm801_info *parent;
- pcm_channel *channel;
- snd_dbuf *buffer;
+ struct pcm_channel *channel;
+ struct snd_dbuf *buffer;
u_int32_t spd, dir, fmt; /* speed, direction, format */
u_int32_t shift;
};
@@ -318,7 +318,7 @@ fm801_intr(void *p)
/* -------------------------------------------------------------------- */
/* channel interface */
static void *
-fm801ch_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+fm801ch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct fm801_info *fm801 = (struct fm801_info *)devinfo;
struct fm801_chinfo *ch = (dir == PCMDIR_PLAY)? &fm801->pch : &fm801->rch;
@@ -504,7 +504,7 @@ fm801ch_getptr(kobj_t obj, void *data)
return result;
}
-static pcmchan_caps *
+static struct pcmchan_caps *
fm801ch_getcaps(kobj_t obj, void *data)
{
return &fm801ch_caps;
@@ -615,9 +615,7 @@ fm801_pci_attach(device_t dev)
fm801->irqid = 0;
fm801->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &fm801->irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
- if (!fm801->irq ||
- bus_setup_intr(dev, fm801->irq, INTR_TYPE_TTY,
- fm801_intr, fm801, &fm801->ih)) {
+ if (!fm801->irq || snd_setup_intr(dev, fm801->irq, 0, fm801_intr, fm801, &fm801->ih)) {
device_printf(dev, "unable to map interrupt\n");
goto oops;
}
@@ -703,7 +701,7 @@ static device_method_t fm801_methods[] = {
static driver_t fm801_driver = {
"pcm",
fm801_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/maestro.c b/sys/dev/sound/pci/maestro.c
index e35e547..2042eaf 100644
--- a/sys/dev/sound/pci/maestro.c
+++ b/sys/dev/sound/pci/maestro.c
@@ -81,8 +81,8 @@
*/
struct agg_chinfo {
struct agg_info *parent;
- pcm_channel *channel;
- snd_dbuf *buffer;
+ struct pcm_channel *channel;
+ struct snd_dbuf *buffer;
bus_addr_t offset;
u_int32_t blocksize;
u_int32_t speed;
@@ -109,6 +109,7 @@ struct agg_info {
bus_addr_t baseaddr;
struct ac97_info *codec;
+ void *lock;
u_int playchns, active;
struct agg_chinfo pch[AGG_MAXPLAYCH];
@@ -637,7 +638,7 @@ set_timer(struct agg_info *ess)
*/
static void *
-aggch_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+aggch_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct agg_info *ess = devinfo;
struct agg_chinfo *ch;
@@ -661,8 +662,7 @@ aggch_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
if (physaddr < ess->baseaddr || ch->offset > WPWA_MAXADDR) {
device_printf(ess->dev,
"offset %#x exceeds limit. ", ch->offset);
- dma_free(ess, b->buf);
- b->buf = NULL;
+ dma_free(ess, sndbuf_getbuf(b));
return NULL;
}
@@ -786,7 +786,7 @@ aggch_getplayptr(kobj_t obj, void *data)
return cp;
}
-static pcmchan_caps *
+static struct pcmchan_caps *
aggch_getcaps(kobj_t obj, void *data)
{
static u_int32_t playfmt[] = {
@@ -798,7 +798,7 @@ aggch_getcaps(kobj_t obj, void *data)
AFMT_STEREO | AFMT_S16_LE,
0
};
- static pcmchan_caps playcaps = {2000, 96000, playfmt, 0};
+ static struct pcmchan_caps playcaps = {2000, 96000, playfmt, 0};
static u_int32_t recfmt[] = {
AFMT_S8,
@@ -807,7 +807,7 @@ aggch_getcaps(kobj_t obj, void *data)
AFMT_STEREO | AFMT_S16_LE,
0
};
- static pcmchan_caps reccaps = {4000, 48000, recfmt, 0};
+ static struct pcmchan_caps reccaps = {4000, 48000, recfmt, 0};
return (((struct agg_chinfo*)data)->dir == PCMDIR_PLAY)?
&playcaps : &reccaps;
@@ -1020,8 +1020,7 @@ agg_attach(device_t dev)
irq = bus_alloc_resource(dev, SYS_RES_IRQ, &irqid,
0, BUS_SPACE_UNRESTRICTED, 1, RF_ACTIVE | RF_SHAREABLE);
- if (irq == NULL
- || bus_setup_intr(dev, irq, INTR_TYPE_TTY, agg_intr, ess, &ih)) {
+ if (irq == NULL || snd_setup_intr(dev, irq, 0, agg_intr, ess, &ih)) {
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
@@ -1183,7 +1182,7 @@ static device_method_t agg_methods[] = {
static driver_t agg_driver = {
"pcm",
agg_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/maestro3.c b/sys/dev/sound/pci/maestro3.c
index 9551dee..375fa31 100644
--- a/sys/dev/sound/pci/maestro3.c
+++ b/sys/dev/sound/pci/maestro3.c
@@ -95,8 +95,8 @@ struct sc_info;
struct sc_pchinfo {
u_int32_t spd;
u_int32_t fmt;
- snd_dbuf *buffer;
- pcm_channel *channel;
+ struct snd_dbuf *buffer;
+ struct pcm_channel *channel;
struct sc_info *parent;
u_int32_t bufsize;
u_int32_t dac_data;
@@ -107,8 +107,8 @@ struct sc_pchinfo {
struct sc_rchinfo {
u_int32_t spd;
u_int32_t fmt;
- snd_dbuf *buffer;
- pcm_channel *channel;
+ struct snd_dbuf *buffer;
+ struct pcm_channel *channel;
struct sc_info *parent;
u_int32_t bufsize;
u_int32_t adc_data;
@@ -145,24 +145,24 @@ struct sc_info {
/* -------------------------------------------------------------------- */
/* play channel interface */
-static void *m3_pchan_init(kobj_t, void *, snd_dbuf *, pcm_channel *, int);
+static void *m3_pchan_init(kobj_t, void *, struct snd_dbuf *, struct pcm_channel *, int);
static int m3_pchan_free(kobj_t, void *);
static int m3_pchan_setformat(kobj_t, void *, u_int32_t);
static int m3_pchan_setspeed(kobj_t, void *, u_int32_t);
static int m3_pchan_setblocksize(kobj_t, void *, u_int32_t);
static int m3_pchan_trigger(kobj_t, void *, int);
static int m3_pchan_getptr(kobj_t, void *);
-static pcmchan_caps *m3_pchan_getcaps(kobj_t, void *);
+static struct pcmchan_caps *m3_pchan_getcaps(kobj_t, void *);
/* record channel interface */
-static void *m3_rchan_init(kobj_t, void *, snd_dbuf *, pcm_channel *, int);
+static void *m3_rchan_init(kobj_t, void *, struct snd_dbuf *, struct pcm_channel *, int);
static int m3_rchan_free(kobj_t, void *);
static int m3_rchan_setformat(kobj_t, void *, u_int32_t);
static int m3_rchan_setspeed(kobj_t, void *, u_int32_t);
static int m3_rchan_setblocksize(kobj_t, void *, u_int32_t);
static int m3_rchan_trigger(kobj_t, void *, int);
static int m3_rchan_getptr(kobj_t, void *);
-static pcmchan_caps *m3_rchan_getcaps(kobj_t, void *);
+static struct pcmchan_caps *m3_rchan_getcaps(kobj_t, void *);
/* talk to the codec - called from ac97.c */
static int m3_initcd(kobj_t, void *);
@@ -200,7 +200,7 @@ static u_int32_t m3_playfmt[] = {
AFMT_STEREO | AFMT_S16_LE,
0
};
-static pcmchan_caps m3_playcaps = {8000, 48000, m3_playfmt, 0};
+static struct pcmchan_caps m3_playcaps = {8000, 48000, m3_playfmt, 0};
static kobj_method_t m3_pch_methods[] = {
KOBJMETHOD(channel_init, m3_pchan_init),
@@ -222,7 +222,7 @@ static u_int32_t m3_recfmt[] = {
AFMT_STEREO | AFMT_S16_LE,
0
};
-static pcmchan_caps m3_reccaps = {8000, 48000, m3_recfmt, 0};
+static struct pcmchan_caps m3_reccaps = {8000, 48000, m3_recfmt, 0};
static kobj_method_t m3_rch_methods[] = {
KOBJMETHOD(channel_init, m3_rchan_init),
@@ -314,7 +314,7 @@ m3_rdcd(kobj_t kobj, void *devinfo, int regno)
return -1;
}
m3_wr_1(sc, CODEC_COMMAND, (regno & 0x7f) | 0x80);
- DELAY(21); /* ac97 cycle = 20.8 usec */
+ DELAY(50); /* ac97 cycle = 20.8 usec */
if (m3_wait(sc)) {
device_printf(sc->dev, "m3_rdcd timed out.\n");
return -1;
@@ -333,6 +333,7 @@ m3_wrcd(kobj_t kobj, void *devinfo, int regno, u_int32_t data)
}
m3_wr_2(sc, CODEC_DATA, data);
m3_wr_1(sc, CODEC_COMMAND, regno & 0x7f);
+ DELAY(50); /* ac97 cycle = 20.8 usec */
return 0;
}
@@ -343,7 +344,7 @@ m3_wrcd(kobj_t kobj, void *devinfo, int regno, u_int32_t data)
#define HI(x) (((x) & 0xffff0000) >> 16)
static void *
-m3_pchan_init(kobj_t kobj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+m3_pchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct sc_info *sc = devinfo;
struct sc_pchinfo *ch;
@@ -609,7 +610,7 @@ m3_pchan_getptr(kobj_t kobj, void *chdata)
return (bus_crnt - bus_base); /* current byte offset of channel */
}
-static pcmchan_caps *
+static struct pcmchan_caps *
m3_pchan_getcaps(kobj_t kobj, void *chdata)
{
struct sc_pchinfo *ch = chdata;
@@ -623,7 +624,7 @@ m3_pchan_getcaps(kobj_t kobj, void *chdata)
/* rec channel interface */
static void *
-m3_rchan_init(kobj_t kobj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+m3_rchan_init(kobj_t kobj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct sc_info *sc = devinfo;
struct sc_rchinfo *ch;
@@ -879,7 +880,7 @@ m3_rchan_getptr(kobj_t kobj, void *chdata)
return (bus_crnt - bus_base); /* current byte offset of channel */
}
-static pcmchan_caps *
+static struct pcmchan_caps *
m3_rchan_getcaps(kobj_t kobj, void *chdata)
{
struct sc_rchinfo *ch = chdata;
@@ -1133,8 +1134,7 @@ m3_pci_attach(device_t dev)
goto bad;
}
- if (bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, m3_intr, sc,
- &sc->ih)) {
+ if (snd_setup_intr(dev, sc->irq, 0, m3_intr, sc, &sc->ih)) {
device_printf(dev, "unable to setup interrupt\n");
goto bad;
}
@@ -1192,6 +1192,7 @@ m3_pci_attach(device_t dev)
device_printf(dev, "attach: pcm_setstatus error\n");
goto bad;
}
+ mixer_hwvol_init(dev);
/* Create the buffer for saving the card state during suspend */
len = sizeof(u_int16_t) * (REV_B_CODE_MEMORY_LENGTH +
@@ -1491,7 +1492,7 @@ static device_method_t m3_methods[] = {
static driver_t m3_driver = {
"pcm",
m3_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/neomagic.c b/sys/dev/sound/pci/neomagic.c
index 5a6ca8c..8771136 100644
--- a/sys/dev/sound/pci/neomagic.c
+++ b/sys/dev/sound/pci/neomagic.c
@@ -48,8 +48,8 @@ struct sc_info;
/* channel registers */
struct sc_chinfo {
int spd, dir, fmt;
- snd_dbuf *buffer;
- pcm_channel *channel;
+ struct snd_dbuf *buffer;
+ struct pcm_channel *channel;
struct sc_info *parent;
};
@@ -117,7 +117,7 @@ static u_int32_t nm_fmt[] = {
AFMT_STEREO | AFMT_S16_LE,
0
};
-static pcmchan_caps nm_caps = {4000, 48000, nm_fmt, 0};
+static struct pcmchan_caps nm_caps = {4000, 48000, nm_fmt, 0};
/* -------------------------------------------------------------------- */
@@ -329,7 +329,7 @@ nm_setch(struct sc_chinfo *ch)
/* channel interface */
static void *
-nmchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+nmchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct sc_info *sc = devinfo;
struct sc_chinfo *ch;
@@ -341,7 +341,7 @@ nmchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
sndbuf_setup(ch->buffer, (u_int8_t *)rman_get_virtual(sc->buf) + chnbuf, NM_BUFFSIZE);
if (bootverbose)
device_printf(sc->dev, "%s buf %p\n", (dir == PCMDIR_PLAY)?
- "play" : "rec", ch->buffer->buf);
+ "play" : "rec", sndbuf_getbuf(ch->buffer));
ch->parent = sc;
ch->channel = c;
ch->dir = dir;
@@ -432,7 +432,7 @@ nmchan_getptr(kobj_t obj, void *data)
return nm_rd(sc, NM_RBUFFER_CURRP, 4) - sc->rbuf;
}
-static pcmchan_caps *
+static struct pcmchan_caps *
nmchan_getcaps(kobj_t obj, void *data)
{
return &nm_caps;
@@ -623,8 +623,7 @@ nm_pci_attach(device_t dev)
sc->irqid = 0;
sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
- if (!sc->irq ||
- bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, nm_intr, sc, &sc->ih)) {
+ if (!sc->irq || snd_setup_intr(dev, sc->irq, 0, nm_intr, sc, &sc->ih)) {
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
@@ -702,7 +701,7 @@ static device_method_t nm_methods[] = {
static driver_t nm_driver = {
"pcm",
nm_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/solo.c b/sys/dev/sound/pci/solo.c
index 71a00f1..d6d7c71 100644
--- a/sys/dev/sound/pci/solo.c
+++ b/sys/dev/sound/pci/solo.c
@@ -55,7 +55,7 @@ static u_int32_t ess_playfmt[] = {
AFMT_STEREO | AFMT_U16_LE,
0
};
-static pcmchan_caps ess_playcaps = {5000, 49000, ess_playfmt, 0};
+static struct pcmchan_caps ess_playcaps = {5000, 49000, ess_playfmt, 0};
/*
* Recording output is byte-swapped
@@ -71,14 +71,14 @@ static u_int32_t ess_recfmt[] = {
AFMT_STEREO | AFMT_U16_BE,
0
};
-static pcmchan_caps ess_reccaps = {5000, 49000, ess_recfmt, 0};
+static struct pcmchan_caps ess_reccaps = {5000, 49000, ess_recfmt, 0};
struct ess_info;
struct ess_chinfo {
struct ess_info *parent;
- pcm_channel *channel;
- snd_dbuf *buffer;
+ struct pcm_channel *channel;
+ struct snd_dbuf *buffer;
int dir, hwch, stopping;
u_int32_t fmt, spd, blksz;
};
@@ -510,7 +510,7 @@ ess_stop(struct ess_chinfo *ch)
/* -------------------------------------------------------------------- */
/* channel interface for ESS18xx */
static void *
-esschan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+esschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct ess_info *sc = devinfo;
struct ess_chinfo *ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch;
@@ -595,7 +595,7 @@ esschan_getptr(kobj_t obj, void *data)
return ess_dmapos(sc, ch->hwch);
}
-static pcmchan_caps *
+static struct pcmchan_caps *
esschan_getcaps(kobj_t obj, void *data)
{
struct ess_chinfo *ch = data;
@@ -618,7 +618,7 @@ CHANNEL_DECLARE(esschan);
/************************************************************/
static int
-essmix_init(snd_mixer *m)
+essmix_init(struct snd_mixer *m)
{
struct ess_info *sc = mix_getdevinfo(m);
@@ -635,7 +635,7 @@ essmix_init(snd_mixer *m)
}
static int
-essmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right)
+essmix_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
{
struct ess_info *sc = mix_getdevinfo(m);
int preg = 0, rreg = 0, l, r;
@@ -695,7 +695,7 @@ essmix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right)
}
static int
-essmix_setrecsrc(snd_mixer *m, u_int32_t src)
+essmix_setrecsrc(struct snd_mixer *m, u_int32_t src)
{
struct ess_info *sc = mix_getdevinfo(m);
u_char recdev;
@@ -944,7 +944,7 @@ ess_attach(device_t dev)
if (sc->newspeed)
ess_setmixer(sc, 0x71, 0x2a);
- bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, ess_intr, sc, &sc->ih);
+ snd_setup_intr(dev, sc->irq, 0, ess_intr, sc, &sc->ih);
if (!sc->duplex)
pcm_setflags(dev, pcm_getflags(dev) | SD_F_SIMPLEX);
@@ -1005,7 +1005,7 @@ static device_method_t ess_methods[] = {
static driver_t ess_driver = {
"pcm",
ess_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
DRIVER_MODULE(snd_solo, pci, ess_driver, pcm_devclass, 0, 0);
diff --git a/sys/dev/sound/pci/t4dwave.c b/sys/dev/sound/pci/t4dwave.c
index b1a3c44..76254cc 100644
--- a/sys/dev/sound/pci/t4dwave.c
+++ b/sys/dev/sound/pci/t4dwave.c
@@ -52,15 +52,15 @@ struct tr_chinfo {
u_int32_t rvol, cvol;
u_int32_t gvsel, pan, vol, ctrl;
int index, bufhalf;
- snd_dbuf *buffer;
- pcm_channel *channel;
+ struct snd_dbuf *buffer;
+ struct pcm_channel *channel;
struct tr_info *parent;
};
struct tr_rchinfo {
u_int32_t delta;
- snd_dbuf *buffer;
- pcm_channel *channel;
+ struct snd_dbuf *buffer;
+ struct pcm_channel *channel;
struct tr_info *parent;
};
@@ -76,6 +76,8 @@ struct tr_info {
int regtype, regid, irqid;
void *ih;
+ void *lock;
+
u_int32_t playchns;
struct tr_chinfo chinfo[TR_MAXPLAYCH];
struct tr_rchinfo recchinfo;
@@ -94,7 +96,7 @@ static u_int32_t tr_recfmt[] = {
AFMT_STEREO | AFMT_U16_LE,
0
};
-static pcmchan_caps tr_reccaps = {4000, 48000, tr_recfmt, 0};
+static struct pcmchan_caps tr_reccaps = {4000, 48000, tr_recfmt, 0};
static u_int32_t tr_playfmt[] = {
AFMT_U8,
@@ -107,7 +109,7 @@ static u_int32_t tr_playfmt[] = {
AFMT_STEREO | AFMT_U16_LE,
0
};
-static pcmchan_caps tr_playcaps = {4000, 48000, tr_playfmt, 0};
+static struct pcmchan_caps tr_playcaps = {4000, 48000, tr_playfmt, 0};
/* -------------------------------------------------------------------- */
@@ -168,9 +170,11 @@ tr_rdcd(kobj_t obj, void *devinfo, int regno)
}
regno &= 0x7f;
+ snd_mtxlock(tr->lock);
tr_wr(tr, treg, regno | trw, 4);
j=trw;
for (i=TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--) j=tr_rd(tr, treg, 4);
+ snd_mtxunlock(tr->lock);
if (i == 0) printf("codec timeout during read of register %x\n", regno);
return (j >> TR_CDC_DATA) & 0xffff;
}
@@ -200,11 +204,13 @@ tr_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data)
printf("tr_wrcd: reg %x was %x", regno, tr_rdcd(devinfo, regno));
#endif
j=trw;
+ snd_mtxlock(tr->lock);
for (i=TR_TIMEOUT_CDC; (i>0) && (j & trw); i--) j=tr_rd(tr, treg, 4);
tr_wr(tr, treg, (data << TR_CDC_DATA) | regno | trw, 4);
#if 0
printf(" - wrote %x, now %x\n", data, tr_rdcd(devinfo, regno));
#endif
+ snd_mtxunlock(tr->lock);
if (i==0) printf("codec timeout writing %x, data %x\n", regno, data);
return (i > 0)? 0 : -1;
}
@@ -250,6 +256,7 @@ tr_enaint(struct tr_chinfo *ch, int enable)
u_int32_t i, reg;
int bank, chan;
+ snd_mtxlock(tr->lock);
bank = (ch->index & 0x20) ? 1 : 0;
chan = ch->index & 0x1f;
reg = bank? TR_REG_INTENB : TR_REG_INTENA;
@@ -260,6 +267,7 @@ tr_enaint(struct tr_chinfo *ch, int enable)
tr_clrint(ch);
tr_wr(tr, reg, i, 4);
+ snd_mtxunlock(tr->lock);
}
/* playback channels */
@@ -336,9 +344,11 @@ tr_wrch(struct tr_chinfo *ch)
cr[3]|=(ch->alpha<<20) | (ch->fms<<16) | (ch->fmc<<14);
break;
}
+ snd_mtxlock(tr->lock);
tr_selch(ch);
for (i=0; i<TR_CHN_REGS; i++)
tr_wr(tr, TR_REG_CHNBASE+(i<<2), cr[i], 4);
+ snd_mtxunlock(tr->lock);
}
static void
@@ -347,9 +357,11 @@ tr_rdch(struct tr_chinfo *ch)
struct tr_info *tr = ch->parent;
u_int32_t cr[5], i;
+ snd_mtxlock(tr->lock);
tr_selch(ch);
for (i=0; i<5; i++)
cr[i]=tr_rd(tr, TR_REG_CHNBASE+(i<<2), 4);
+ snd_mtxunlock(tr->lock);
ch->lba= (cr[1] & 0x3fffffff);
@@ -396,7 +408,7 @@ tr_fmttobits(u_int32_t fmt)
/* channel interface */
static void *
-trpchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+trpchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct tr_info *tr = devinfo;
struct tr_chinfo *ch;
@@ -480,7 +492,7 @@ trpchan_getptr(kobj_t obj, void *data)
return ch->cso * sndbuf_getbps(ch->buffer);
}
-static pcmchan_caps *
+static struct pcmchan_caps *
trpchan_getcaps(kobj_t obj, void *data)
{
return &tr_playcaps;
@@ -502,7 +514,7 @@ CHANNEL_DECLARE(trpchan);
/* rec channel interface */
static void *
-trrchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+trrchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct tr_info *tr = devinfo;
struct tr_rchinfo *ch;
@@ -600,7 +612,7 @@ trrchan_getptr(kobj_t obj, void *data)
return tr_rd(tr, TR_REG_DMAR0, 4) - vtophys(sndbuf_getbuf(ch->buffer));
}
-static pcmchan_caps *
+static struct pcmchan_caps *
trrchan_getcaps(kobj_t obj, void *data)
{
return &tr_reccaps;
@@ -646,9 +658,7 @@ tr_intr(void *p)
if (ch->bufhalf != tmp) {
chn_intr(ch->channel);
ch->bufhalf = tmp;
- } else
- printf("same bufhalf\n");
-
+ }
}
}
chnum++;
@@ -716,6 +726,7 @@ tr_pci_attach(device_t dev)
bzero(tr, sizeof(*tr));
tr->type = pci_get_devid(dev);
+ tr->lock = snd_mtxcreate(device_get_nameunit(dev));
data = pci_read_config(dev, PCIR_COMMAND, 2);
data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
@@ -745,8 +756,7 @@ tr_pci_attach(device_t dev)
tr->irqid = 0;
tr->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &tr->irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
- if (!tr->irq ||
- bus_setup_intr(dev, tr->irq, INTR_TYPE_TTY, tr_intr, tr, &tr->ih)) {
+ if (!tr->irq || snd_setup_intr(dev, tr->irq, INTR_MPSAFE, tr_intr, tr, &tr->ih)) {
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
@@ -778,6 +788,7 @@ bad:
if (tr->ih) bus_teardown_intr(dev, tr->irq, tr->ih);
if (tr->irq) bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq);
if (tr->parent_dmat) bus_dma_tag_destroy(tr->parent_dmat);
+ if (tr->lock) snd_mtxfree(tr->lock);
free(tr, M_DEVBUF);
return ENXIO;
}
@@ -797,6 +808,7 @@ tr_pci_detach(device_t dev)
bus_teardown_intr(dev, tr->irq, tr->ih);
bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq);
bus_dma_tag_destroy(tr->parent_dmat);
+ snd_mtxfree(tr->lock);
free(tr, M_DEVBUF);
return 0;
@@ -814,7 +826,7 @@ static device_method_t tr_methods[] = {
static driver_t tr_driver = {
"pcm",
tr_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/via82c686.c b/sys/dev/sound/pci/via82c686.c
index 5f5a2b1..7450e2a 100644
--- a/sys/dev/sound/pci/via82c686.c
+++ b/sys/dev/sound/pci/via82c686.c
@@ -36,12 +36,12 @@
#include <dev/sound/pci/via82c686.h>
#define VIA_PCI_ID 0x30581106
-#define NSEGS 16 /* Number of segments in SGD table */
+#define NSEGS 4 /* Number of segments in SGD table */
#define SEGS_PER_CHAN (NSEGS/2)
#define TIMEOUT 50
-#define VIA_BUFFSIZE 0x4000
+#define VIA_BUFFSIZE 0x1000
#undef DEB
#define DEB(x)
@@ -60,9 +60,11 @@ struct via_info;
struct via_chinfo {
struct via_info *parent;
- pcm_channel *channel;
- snd_dbuf *buffer;
- int dir;
+ struct pcm_channel *channel;
+ struct snd_dbuf *buffer;
+ struct via_dma_op *sgd_table;
+ int dir, blksz;
+ int base, count, mode, ctrl;
};
struct via_info {
@@ -70,39 +72,27 @@ struct via_info {
bus_space_handle_t sh;
bus_dma_tag_t parent_dmat;
bus_dma_tag_t sgd_dmat;
+ bus_dmamap_t sgd_dmamap;
struct resource *reg, *irq;
int regid, irqid;
void *ih;
+ struct ac97_info *codec;
struct via_chinfo pch, rch;
struct via_dma_op *sgd_table;
u_int16_t codec_caps;
};
-static u_int32_t via_rd(struct via_info *via, int regno, int size);
-static void via_wr(struct via_info *, int regno, u_int32_t data, int size);
-
-static void via_intr(void *);
-bus_dmamap_callback_t dma_cb;
-
-static u_int32_t via_playfmt[] = {
- AFMT_U8,
- AFMT_STEREO | AFMT_U8,
- AFMT_S16_LE,
- AFMT_STEREO | AFMT_S16_LE,
- 0
-};
-static pcmchan_caps via_playcaps = {4000, 48000, via_playfmt, 0};
-
-static u_int32_t via_recfmt[] = {
+static u_int32_t via_fmt[] = {
AFMT_U8,
AFMT_STEREO | AFMT_U8,
AFMT_S16_LE,
AFMT_STEREO | AFMT_S16_LE,
0
};
-static pcmchan_caps via_reccaps = {4000, 48000, via_recfmt, 0};
+static struct pcmchan_caps via_vracaps = {4000, 48000, via_fmt, 0};
+static struct pcmchan_caps via_caps = {48000, 48000, via_fmt, 0};
static u_int32_t
via_rd(struct via_info *via, int regno, int size)
@@ -184,8 +174,7 @@ via_write_codec(kobj_t obj, void *addr, int reg, u_int32_t val)
if (via_waitready_codec(via)) return -1;
- via_wr(via, VIA_CODEC_CTL,
- VIA_CODEC_PRIVALID | VIA_CODEC_INDEX(reg) | val, 4);
+ via_wr(via, VIA_CODEC_CTL, VIA_CODEC_PRIVALID | VIA_CODEC_INDEX(reg) | val, 4);
return 0;
}
@@ -197,16 +186,15 @@ via_read_codec(kobj_t obj, void *addr, int reg)
struct via_info *via = addr;
if (via_waitready_codec(via))
- return 1;
+ return -1;
- via_wr(via, VIA_CODEC_CTL,
- VIA_CODEC_PRIVALID | VIA_CODEC_READ | VIA_CODEC_INDEX(reg),4);
+ via_wr(via, VIA_CODEC_CTL, VIA_CODEC_PRIVALID | VIA_CODEC_READ | VIA_CODEC_INDEX(reg),4);
if (via_waitready_codec(via))
- return 1;
+ return -1;
if (via_waitvalid_codec(via))
- return 1;
+ return -1;
return via_rd(via, VIA_CODEC_CTL, 2);
}
@@ -220,58 +208,60 @@ AC97_DECLARE(via_ac97);
/* -------------------------------------------------------------------- */
-/* channel interface */
-static void *
-viachan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
-{
- struct via_info *via = devinfo;
- struct via_chinfo *ch = (dir == PCMDIR_PLAY) ? &via->pch : &via->rch;
-
- ch->parent = via;
- ch->channel = c;
- ch->buffer = b;
-
- if (sndbuf_alloc(ch->buffer, via->parent_dmat, VIA_BUFFSIZE) == -1) return NULL;
- return ch;
-}
-
static int
-viachan_setdir(kobj_t obj, void *data, int dir)
+via_buildsgdt(struct via_chinfo *ch)
{
- struct via_chinfo *ch = data;
- struct via_info *via = ch->parent;
- struct via_dma_op *ado;
- int i, chunk_size;
- int phys_addr, flag;
+ u_int32_t phys_addr, flag;
+ int i, segs, seg_size;
- ch->dir = dir;
/*
* Build the scatter/gather DMA (SGD) table.
* There are four slots in the table: two for play, two for record.
* This creates two half-buffers, one of which is playing; the other
* is feeding.
*/
- ado = via->sgd_table;
- chunk_size = sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN;
+ seg_size = ch->blksz;
+ segs = sndbuf_getsize(ch->buffer) / seg_size;
+ phys_addr = vtophys(sndbuf_getbuf(ch->buffer));
- if (dir == PCMDIR_REC) {
- ado += SEGS_PER_CHAN;
+ for (i = 0; i < segs; i++) {
+ flag = (i == segs - 1)? VIA_DMAOP_EOL : VIA_DMAOP_FLAG;
+ ch->sgd_table[i].ptr = phys_addr + (i * seg_size);
+ ch->sgd_table[i].flags = flag | seg_size;
}
- DEB(printf("SGD table located at va %p\n", ado));
- phys_addr = vtophys(sndbuf_getbuf(ch->buffer));
- for (i = 0; i < SEGS_PER_CHAN; i++) {
- ado->ptr = phys_addr;
- flag = (i == SEGS_PER_CHAN-1) ?
- VIA_DMAOP_EOL : VIA_DMAOP_FLAG;
- ado->flags = flag | chunk_size;
- DEB(printf("ado->ptr/flags = %x/%x\n", phys_addr, flag));
- phys_addr += chunk_size;
- ado++;
- }
return 0;
}
+/* channel interface */
+static void *
+viachan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
+{
+ struct via_info *via = devinfo;
+ struct via_chinfo *ch = (dir == PCMDIR_PLAY)? &via->pch : &via->rch;
+
+ ch->parent = via;
+ ch->channel = c;
+ ch->buffer = b;
+ ch->dir = dir;
+ ch->sgd_table = &via->sgd_table[(dir == PCMDIR_PLAY)? 0 : SEGS_PER_CHAN];
+ if (ch->dir == PCMDIR_PLAY) {
+ ch->base = VIA_PLAY_DMAOPS_BASE;
+ ch->count = VIA_PLAY_DMAOPS_COUNT;
+ ch->ctrl = VIA_RECORD_CONTROL;
+ ch->mode = VIA_PLAY_MODE;
+ } else {
+ ch->base = VIA_RECORD_DMAOPS_BASE;
+ ch->count = VIA_RECORD_DMAOPS_COUNT;
+ ch->ctrl = VIA_PLAY_CONTROL;
+ ch->mode = VIA_RECORD_MODE;
+ }
+
+ if (sndbuf_alloc(ch->buffer, via->parent_dmat, VIA_BUFFSIZE) == -1)
+ return NULL;
+ return ch;
+}
+
static int
viachan_setformat(kobj_t obj, void *data, u_int32_t format)
{
@@ -285,21 +275,11 @@ viachan_setformat(kobj_t obj, void *data, u_int32_t format)
if (format & AFMT_S16_LE)
mode_set |= VIA_RPMODE_16BIT;
- /* Set up for output format */
- if (ch->dir == PCMDIR_PLAY) {
- DEB(printf("set play format: %x\n", format));
- mode = via_rd(via, VIA_PLAY_MODE, 1);
- mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO);
- mode |= mode_set;
- via_wr(via, VIA_PLAY_MODE, mode, 1);
- }
- else {
- DEB(printf("set record format: %x\n", format));
- mode = via_rd(via, VIA_RECORD_MODE, 1);
+ DEB(printf("set format: dir = %d, format=%x\n", ch->dir, format));
+ mode = via_rd(via, ch->mode, 1);
mode &= ~(VIA_RPMODE_16BIT | VIA_RPMODE_STEREO);
mode |= mode_set;
- via_wr(via, VIA_RECORD_MODE, mode, 1);
- }
+ via_wr(via, ch->mode, mode, 1);
return 0;
}
@@ -309,6 +289,7 @@ viachan_setspeed(kobj_t obj, void *data, u_int32_t speed)
{
struct via_chinfo *ch = data;
struct via_info *via = ch->parent;
+ int reg;
/*
* Basic AC'97 defines a 48 kHz sample rate only. For other rates,
@@ -319,31 +300,11 @@ viachan_setspeed(kobj_t obj, void *data, u_int32_t speed)
* itself), then negotiate the rate with the codec. Otherwise,
* return 48 kHz cuz that's all you got.
*/
- if (ch->dir == PCMDIR_PLAY) {
- DEB(printf("requested play speed: %d\n", speed));
- if (via->codec_caps & AC97_CODEC_DOES_VRA) {
- via_write_codec(NULL, via, AC97_REG_EXT_DAC_RATE, speed);
- speed = via_read_codec(NULL, via, AC97_REG_EXT_DAC_RATE);
- }
- else {
- DEB(printf("VRA not supported!\n"));
- speed = 48000;
- }
- DEB(printf("obtained play speed: %d\n", speed));
- }
- else {
- DEB(printf("requested record speed: %d\n", speed));
- if (via->codec_caps & AC97_CODEC_DOES_VRA) {
- via_write_codec(NULL, via, AC97_REG_EXT_ADC_RATE, speed);
- speed = via_read_codec(NULL, via, AC97_REG_EXT_ADC_RATE);
- }
- else {
- DEB(printf("VRA not supported!\n"));
- speed = 48000;
- }
- DEB(printf("obtained record speed: %d\n", speed));
- }
- return speed;
+ if (via->codec_caps & AC97_EXTCAP_VRA) {
+ reg = (ch->dir == PCMDIR_PLAY)? AC97_REGEXT_FDACRATE : AC97_REGEXT_LADCRATE;
+ return ac97_setrate(via->codec, reg, speed);
+ } else
+ return 48000;
}
static int
@@ -351,7 +312,10 @@ viachan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
{
struct via_chinfo *ch = data;
- return sndbuf_getsize(ch->buffer) / 2;
+ ch->blksz = blocksize;
+ sndbuf_resize(ch->buffer, SEGS_PER_CHAN, ch->blksz);
+
+ return ch->blksz;
}
static int
@@ -361,37 +325,20 @@ viachan_trigger(kobj_t obj, void *data, int go)
struct via_info *via = ch->parent;
struct via_dma_op *ado;
- if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) return 0;
- if (ch->dir == PCMDIR_PLAY) {
- if (go == PCMTRIG_START) {
- ado = &via->sgd_table[0];
+ if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
+ return 0;
+
+ ado = ch->sgd_table;
DEB(printf("ado located at va=%p pa=%x\n", ado, vtophys(ado)));
- via_wr(via, VIA_PLAY_DMAOPS_BASE, vtophys(ado),4);
- via_wr(via, VIA_PLAY_CONTROL,
- VIA_RPCTRL_START, 1);
- }
- else {
- /* Stop DMA */
- via_wr(via, VIA_PLAY_CONTROL,
- VIA_RPCTRL_TERMINATE, 1);
- }
- } else {
+
if (go == PCMTRIG_START) {
- ado = &via->sgd_table[SEGS_PER_CHAN];
- DEB(printf("ado located at va=%p pa=%x\n", ado, vtophys(ado)));
- via_wr(via, VIA_RECORD_DMAOPS_BASE,
- vtophys(ado),4);
- via_wr(via, VIA_RECORD_CONTROL,
- VIA_RPCTRL_START, 1);
- }
- else {
- /* Stop DMA */
- via_wr(via, VIA_RECORD_CONTROL,
- VIA_RPCTRL_TERMINATE, 1);
- }
- }
+ via_buildsgdt(ch);
+ via_wr(via, ch->base, vtophys(ado), 4);
+ via_wr(via, ch->ctrl, VIA_RPCTRL_START, 1);
+ } else
+ via_wr(via, ch->ctrl, VIA_RPCTRL_TERMINATE, 1);
-DEB(printf("viachan_trigger: go=%d\n", go));
+ DEB(printf("viachan_trigger: go=%d\n", go));
return 0;
}
@@ -401,68 +348,47 @@ viachan_getptr(kobj_t obj, void *data)
struct via_chinfo *ch = data;
struct via_info *via = ch->parent;
struct via_dma_op *ado;
- int ptr, base, len, seg;
- int base1;
+ int ptr, base, base1, len, seg;
- if (ch->dir == PCMDIR_PLAY) {
- ado = &via->sgd_table[0];
- base1 = via_rd(via, VIA_PLAY_DMAOPS_BASE, 4);
- len = via_rd(via, VIA_PLAY_DMAOPS_COUNT, 4);
- base = via_rd(via, VIA_PLAY_DMAOPS_BASE, 4);
- if (base != base1) { /* Avoid race hazzard */
- len = via_rd(via, VIA_PLAY_DMAOPS_COUNT, 4);
- }
- DEB(printf("viachan_getptr: len / base = %x / %x\n", len, base));
-
- /* Base points to SGD segment to do, one past current */
-
- /* Determine how many segments have been done */
- seg = (base - vtophys(ado)) / sizeof(struct via_dma_op);
- if (seg == 0) seg = SEGS_PER_CHAN;
+ ado = ch->sgd_table;
+ base1 = via_rd(via, ch->base, 4);
+ len = via_rd(via, ch->count, 4);
+ base = via_rd(via, ch->base, 4);
+ if (base != base1) /* Avoid race hazard */
+ len = via_rd(via, ch->count, 4);
- /* Now work out offset: seg less count */
- ptr = seg * sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN - len;
- DEB(printf("return ptr=%d\n", ptr));
- return ptr;
- }
- else {
- base1 = via_rd(via, VIA_RECORD_DMAOPS_BASE, 4);
- ado = &via->sgd_table[SEGS_PER_CHAN];
- len = via_rd(via, VIA_RECORD_DMAOPS_COUNT, 4);
- base = via_rd(via, VIA_RECORD_DMAOPS_BASE, 4);
- if (base != base1) { /* Avoid race hazzard */
- len = via_rd(via, VIA_RECORD_DMAOPS_COUNT, 4);
- }
DEB(printf("viachan_getptr: len / base = %x / %x\n", len, base));
- /* Base points to next block to do, one past current */
+ /* Base points to SGD segment to do, one past current */
/* Determine how many segments have been done */
seg = (base - vtophys(ado)) / sizeof(struct via_dma_op);
- if (seg == 0) seg = SEGS_PER_CHAN;
+ if (seg == 0)
+ seg = SEGS_PER_CHAN;
/* Now work out offset: seg less count */
- ptr = seg * sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN - len;
-
+ ptr = (seg * sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN) - len;
+ if (ch->dir == PCMDIR_REC) {
/* DMA appears to operate on memory 'lines' of 32 bytes */
/* so don't return any part line - it isn't in RAM yet */
ptr = ptr & ~0x1f;
+ }
+
DEB(printf("return ptr=%d\n", ptr));
return ptr;
- }
- return 0;
}
-static pcmchan_caps *
+static struct pcmchan_caps *
viachan_getcaps(kobj_t obj, void *data)
{
struct via_chinfo *ch = data;
- return (ch->dir == PCMDIR_PLAY) ? &via_playcaps : &via_reccaps;
+ struct via_info *via = ch->parent;
+
+ return (via->codec_caps & AC97_EXTCAP_VRA)? &via_vracaps : &via_caps;
}
static kobj_method_t viachan_methods[] = {
KOBJMETHOD(channel_init, viachan_init),
- KOBJMETHOD(channel_setdir, viachan_setdir),
KOBJMETHOD(channel_setformat, viachan_setformat),
KOBJMETHOD(channel_setspeed, viachan_setspeed),
KOBJMETHOD(channel_setblocksize, viachan_setblocksize),
@@ -511,7 +437,8 @@ via_probe(device_t dev)
}
-void dma_cb(void *p, bus_dma_segment_t *bds, int a, int b)
+static void
+dma_cb(void *p, bus_dma_segment_t *bds, int a, int b)
{
}
@@ -520,14 +447,9 @@ static int
via_attach(device_t dev)
{
struct via_info *via = 0;
- struct ac97_info *codec = 0;
char status[SND_STATUSLEN];
-
u_int32_t data;
- u_int16_t v;
- bus_dmamap_t sgd_dma_map;
-
if ((via = malloc(sizeof *via, M_DEVBUF, M_NOWAIT)) == NULL) {
device_printf(dev, "cannot allocate softc\n");
return ENXIO;
@@ -541,12 +463,10 @@ via_attach(device_t dev)
data = pci_read_config(dev, PCIR_COMMAND, 2);
pci_write_config(dev, VIA_PCICONF_MISC,
- VIA_PCICONF_ACLINKENAB | VIA_PCICONF_ACSGD |
- VIA_PCICONF_ACNOTRST | VIA_PCICONF_ACVSR, 1);
+ VIA_PCICONF_ACLINKENAB | VIA_PCICONF_ACSGD | VIA_PCICONF_ACNOTRST | VIA_PCICONF_ACVSR, 1);
via->regid = PCIR_MAPS;
- via->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &via->regid,
- 0, ~0, 1, RF_ACTIVE);
+ via->reg = bus_alloc_resource(dev, SYS_RES_IOPORT, &via->regid, 0, ~0, 1, RF_ACTIVE);
if (!via->reg) {
device_printf(dev, "cannot allocate bus resource.");
goto bad;
@@ -555,44 +475,24 @@ via_attach(device_t dev)
via->sh = rman_get_bushandle(via->reg);
via->irqid = 0;
- via->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &via->irqid,
- 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
- if (!via->irq
- || bus_setup_intr(dev, via->irq, INTR_TYPE_TTY, via_intr, via, &via->ih)){
+ via->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &via->irqid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
+ if (!via->irq || snd_setup_intr(dev, via->irq, 0, via_intr, via, &via->ih)) {
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
- via_wr(via, VIA_PLAY_MODE,
- VIA_RPMODE_AUTOSTART |
- VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1);
- via_wr(via, VIA_RECORD_MODE,
- VIA_RPMODE_AUTOSTART |
- VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1);
+ via_wr(via, VIA_PLAY_MODE, VIA_RPMODE_AUTOSTART | VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1);
+ via_wr(via, VIA_RECORD_MODE, VIA_RPMODE_AUTOSTART | VIA_RPMODE_INTR_FLAG | VIA_RPMODE_INTR_EOL, 1);
- codec = AC97_CREATE(dev, via, via_ac97);
- if (!codec) goto bad;
+ via->codec = AC97_CREATE(dev, via, via_ac97);
+ if (!via->codec)
+ goto bad;
- mixer_init(dev, ac97_getmixerclass(), codec);
+ mixer_init(dev, ac97_getmixerclass(), via->codec);
- /*
- * The mixer init resets the codec. So enabling VRA must be done
- * afterwards.
- */
- v = via_read_codec(NULL, via, AC97_REG_EXT_AUDIO_ID);
- v &= (AC97_ENAB_VRA | AC97_ENAB_MICVRA);
- via_write_codec(NULL, via, AC97_REG_EXT_AUDIO_STAT, v);
- via->codec_caps = v;
- {
- v = via_read_codec(NULL, via, AC97_REG_EXT_AUDIO_STAT);
- DEB(printf("init: codec stat: %d\n", v));
- }
-
- if (!(v & AC97_CODEC_DOES_VRA)) {
- /* no VRA => can do only 48 kbps */
- via_playcaps.minspeed = 48000;
- via_reccaps.minspeed = 48000;
- }
+ via->codec_caps = ac97_getextcaps(via->codec);
+ if (via->codec_caps & AC97_EXTCAP_VRA)
+ ac97_setextmode(via->codec, AC97_EXTCAP_VRA | AC97_EXTCAP_VRM);
/* DMA tag for buffers */
if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
@@ -621,13 +521,12 @@ via_attach(device_t dev)
goto bad;
}
- if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table,
- BUS_DMA_NOWAIT, &sgd_dma_map) == -1) goto bad;
- if (bus_dmamap_load(via->sgd_dmat, sgd_dma_map, via->sgd_table,
- NSEGS * sizeof(struct via_dma_op), dma_cb, 0, 0)) goto bad;
+ if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1)
+ goto bad;
+ if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table, NSEGS * sizeof(struct via_dma_op), dma_cb, 0, 0))
+ goto bad;
- snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld",
- rman_get_start(via->reg), rman_get_start(via->irq));
+ snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld", rman_get_start(via->reg), rman_get_start(via->irq));
/* Register */
if (pcm_register(dev, via, 1, 1)) goto bad;
@@ -636,11 +535,12 @@ via_attach(device_t dev)
pcm_setstatus(dev, status);
return 0;
bad:
- if (codec) ac97_destroy(codec);
+ if (via->codec) ac97_destroy(via->codec);
if (via->reg) bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg);
if (via->ih) bus_teardown_intr(dev, via->irq, via->ih);
if (via->irq) bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
if (via->parent_dmat) bus_dma_tag_destroy(via->parent_dmat);
+ if (via->sgd_dmamap) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat);
if (via) free(via, M_DEVBUF);
return ENXIO;
@@ -661,6 +561,7 @@ via_detach(device_t dev)
bus_teardown_intr(dev, via->irq, via->ih);
bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq);
bus_dma_tag_destroy(via->parent_dmat);
+ bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap);
bus_dma_tag_destroy(via->sgd_dmat);
free(via, M_DEVBUF);
return 0;
@@ -677,7 +578,7 @@ static device_method_t via_methods[] = {
static driver_t via_driver = {
"pcm",
via_methods,
- sizeof(snddev_info),
+ sizeof(struct snddev_info),
};
static devclass_t pcm_devclass;
diff --git a/sys/dev/sound/pci/vibes.c b/sys/dev/sound/pci/vibes.c
index 28ce36f..228b281 100644
--- a/sys/dev/sound/pci/vibes.c
+++ b/sys/dev/sound/pci/vibes.c
@@ -56,8 +56,8 @@ struct sc_info;
struct sc_chinfo {
struct sc_info *parent;
- pcm_channel *channel;
- snd_dbuf *buffer;
+ struct pcm_channel *channel;
+ struct snd_dbuf *buffer;
u_int32_t fmt, spd;
int dir;
int dma_active, dma_was_active;
@@ -100,7 +100,7 @@ static u_int32_t sc_fmt[] = {
0
};
-static pcmchan_caps sc_caps = {8000, 48000, sc_fmt, 0};
+static struct pcmchan_caps sc_caps = {8000, 48000, sc_fmt, 0};
/* ------------------------------------------------------------------------- */
/* Register Manipulations */
@@ -178,7 +178,7 @@ sv_dma_get_count(bus_space_tag_t st, bus_space_handle_t sh)
/* Play / Record Common Interface */
static void *
-svchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
+svchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, struct pcm_channel *c, int dir)
{
struct sc_info *sc = devinfo;
struct sc_chinfo *ch;
@@ -200,7 +200,7 @@ svchan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir)
return ch;
}
-static pcmchan_caps *
+static struct pcmchan_caps *
svchan_getcaps(kobj_t obj, void *data)
{
return &sc_caps;
@@ -505,7 +505,7 @@ sv_mix_mute_all(struct sc_info *sc)
}
static int
-sv_mix_init(snd_mixer *m)
+sv_mix_init(struct snd_mixer *m)
{
u_int32_t i, v;
@@ -523,14 +523,14 @@ sv_mix_init(snd_mixer *m)
}
static int
-sv_mix_set(snd_mixer *m, u_int32_t dev, u_int32_t left, u_int32_t right)
+sv_mix_set(struct snd_mixer *m, u_int32_t dev, u_int32_t left, u_int32_t right)
{
struct sc_info *sc = mix_getdevinfo(m);
return sv_gain(sc, dev, left, right);
}
static int
-sv_mix_setrecsrc(snd_mixer *m, u_int32_t mask)
+sv_mix_setrecsrc(struct snd_mixer *m, u_int32_t mask)
{
struct sc_info *sc = mix_getdevinfo(m);
u_int32_t i, v;
@@ -706,7 +706,7 @@ sv_probe(device_t dev)
static int
sv_attach(device_t dev) {
- snddev_info *d;
+ struct snddev_info *d;
struct sc_info *sc;
u_int32_t data;
char status[SND_STATUSLEN];
@@ -920,7 +920,7 @@ static device_method_t sc_methods[] = {
static driver_t sonicvibes_driver = {
"pcm",
sc_methods,
- sizeof(snddev_info)
+ sizeof(struct snddev_info)
};
static devclass_t pcm_devclass;
OpenPOWER on IntegriCloud