summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorcg <cg@FreeBSD.org>2000-10-26 20:46:58 +0000
committercg <cg@FreeBSD.org>2000-10-26 20:46:58 +0000
commitf395b4d615e2d160af36c0e6100a369313ee0f57 (patch)
treeca8fa72d60bbfa8c609c827877784f53e83597ac /sys
parentd877bb8d5ab3055fcfe9301216cce1bb9d29baea (diff)
downloadFreeBSD-src-f395b4d615e2d160af36c0e6100a369313ee0f57.zip
FreeBSD-src-f395b4d615e2d160af36c0e6100a369313ee0f57.tar.gz
add reinit functions to mixers
unstaticize chn_start() add reset/resetdone functions to channels
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/sound/isa/ad1816.c1
-rw-r--r--sys/dev/sound/isa/ess.c1
-rw-r--r--sys/dev/sound/isa/mss.c2
-rw-r--r--sys/dev/sound/isa/sb.c1
-rw-r--r--sys/dev/sound/isa/sb16.c1
-rw-r--r--sys/dev/sound/isa/sb8.c1
-rw-r--r--sys/dev/sound/pci/solo.c1
-rw-r--r--sys/dev/sound/pcm/ac97.c55
-rw-r--r--sys/dev/sound/pcm/ac97.h2
-rw-r--r--sys/dev/sound/pcm/channel.c28
-rw-r--r--sys/dev/sound/pcm/channel.h1
-rw-r--r--sys/dev/sound/pcm/datatypes.h8
-rw-r--r--sys/dev/sound/pcm/mixer.c19
13 files changed, 100 insertions, 21 deletions
diff --git a/sys/dev/sound/isa/ad1816.c b/sys/dev/sound/isa/ad1816.c
index d25931e..3184dd8 100644
--- a/sys/dev/sound/isa/ad1816.c
+++ b/sys/dev/sound/isa/ad1816.c
@@ -71,6 +71,7 @@ static snd_mixer ad1816_mixer = {
"ad1816 mixer",
ad1816mix_init,
NULL,
+ NULL,
ad1816mix_set,
ad1816mix_setrecsrc,
};
diff --git a/sys/dev/sound/isa/ess.c b/sys/dev/sound/isa/ess.c
index 7b1bddf..7841e35 100644
--- a/sys/dev/sound/isa/ess.c
+++ b/sys/dev/sound/isa/ess.c
@@ -150,6 +150,7 @@ static snd_mixer ess_mixer = {
"ESS mixer",
essmix_init,
NULL,
+ NULL,
essmix_set,
essmix_setrecsrc,
};
diff --git a/sys/dev/sound/isa/mss.c b/sys/dev/sound/isa/mss.c
index 0af216f..3b24a75 100644
--- a/sys/dev/sound/isa/mss.c
+++ b/sys/dev/sound/isa/mss.c
@@ -112,6 +112,7 @@ static snd_mixer mss_mixer = {
"MSS mixer",
mssmix_init,
NULL,
+ NULL,
mssmix_set,
mssmix_setrecsrc,
};
@@ -123,6 +124,7 @@ static snd_mixer yamaha_mixer = {
"OPL3-SAx mixer",
ymmix_init,
NULL,
+ NULL,
ymmix_set,
ymmix_setrecsrc,
};
diff --git a/sys/dev/sound/isa/sb.c b/sys/dev/sound/isa/sb.c
index 6d9154a..7f049bf 100644
--- a/sys/dev/sound/isa/sb.c
+++ b/sys/dev/sound/isa/sb.c
@@ -164,6 +164,7 @@ static snd_mixer sb_mixer = {
"SoundBlaster mixer",
sbmix_init,
NULL,
+ NULL,
sbmix_set,
sbmix_setrecsrc,
};
diff --git a/sys/dev/sound/isa/sb16.c b/sys/dev/sound/isa/sb16.c
index 6d9154a..7f049bf 100644
--- a/sys/dev/sound/isa/sb16.c
+++ b/sys/dev/sound/isa/sb16.c
@@ -164,6 +164,7 @@ static snd_mixer sb_mixer = {
"SoundBlaster mixer",
sbmix_init,
NULL,
+ NULL,
sbmix_set,
sbmix_setrecsrc,
};
diff --git a/sys/dev/sound/isa/sb8.c b/sys/dev/sound/isa/sb8.c
index 6d9154a..7f049bf 100644
--- a/sys/dev/sound/isa/sb8.c
+++ b/sys/dev/sound/isa/sb8.c
@@ -164,6 +164,7 @@ static snd_mixer sb_mixer = {
"SoundBlaster mixer",
sbmix_init,
NULL,
+ NULL,
sbmix_set,
sbmix_setrecsrc,
};
diff --git a/sys/dev/sound/pci/solo.c b/sys/dev/sound/pci/solo.c
index e59c58f..672c7a0 100644
--- a/sys/dev/sound/pci/solo.c
+++ b/sys/dev/sound/pci/solo.c
@@ -149,6 +149,7 @@ static snd_mixer ess_mixer = {
"ESS mixer",
essmix_init,
NULL,
+ NULL,
essmix_set,
essmix_setrecsrc,
};
diff --git a/sys/dev/sound/pcm/ac97.c b/sys/dev/sound/pcm/ac97.c
index d974bf2..3a8bf36 100644
--- a/sys/dev/sound/pcm/ac97.c
+++ b/sys/dev/sound/pcm/ac97.c
@@ -203,6 +203,18 @@ ac97_setextmode(struct ac97_info *codec, u_int16_t mode)
return (mode == codec->extstat)? 0 : -1;
}
+u_int16_t
+ac97_getextmode(struct ac97_info *codec)
+{
+ return codec->extstat;
+}
+
+u_int16_t
+ac97_getextcaps(struct ac97_info *codec)
+{
+ return codec->extcaps;
+}
+
static int
ac97_setrecsrc(struct ac97_info *codec, int channel)
{
@@ -305,6 +317,7 @@ ac97_initmixer(struct ac97_info *codec)
}
} else
codec->count = 1;
+
wrcd(codec, AC97_REG_POWER, 0);
wrcd(codec, AC97_REG_RESET, 0);
DELAY(100000);
@@ -383,6 +396,37 @@ ac97_initmixer(struct ac97_info *codec)
return 0;
}
+static unsigned
+ac97_reinitmixer(struct ac97_info *codec)
+{
+ unsigned i;
+
+ if (codec->init) {
+ codec->count = codec->init(codec->devinfo);
+ if (codec->count == 0) {
+ device_printf(codec->dev, "ac97 codec init failed\n");
+ return ENODEV;
+ }
+ } else
+ codec->count = 1;
+
+ wrcd(codec, AC97_REG_POWER, 0);
+ wrcd(codec, AC97_REG_RESET, 0);
+ DELAY(100000);
+ i = rdcd(codec, AC97_REG_RESET);
+
+ if (!codec->noext) {
+ wrcd(codec, AC97_REGEXT_STAT, codec->extstat);
+ if (rdcd(codec, AC97_REGEXT_STAT) != codec->extstat)
+ device_printf(codec->dev, "ac97 codec failed to reset extended mode (%x, got %x)\n",
+ codec->extstat, rdcd(codec, AC97_REGEXT_STAT));
+ }
+
+ if ((rdcd(codec, AC97_REG_POWER) & 2) == 0)
+ device_printf(codec->dev, "ac97 codec reports dac not ready\n");
+ return 0;
+}
+
struct ac97_info *
ac97_create(device_t dev, void *devinfo, ac97_init *init, ac97_read *rd, ac97_write *wr)
{
@@ -445,6 +489,16 @@ ac97mix_uninit(snd_mixer *m)
}
static int
+ac97mix_reinit(snd_mixer *m)
+{
+ struct ac97_info *codec = mix_getdevinfo(m);
+
+ if (codec == NULL)
+ return -1;
+ return ac97_reinitmixer(codec);
+}
+
+static int
ac97mix_set(snd_mixer *m, unsigned dev, unsigned left, unsigned right)
{
struct ac97_info *codec = mix_getdevinfo(m);
@@ -472,6 +526,7 @@ snd_mixer ac97_mixer = {
"AC97 mixer",
ac97mix_init,
ac97mix_uninit,
+ ac97mix_reinit,
ac97mix_set,
ac97mix_setrecsrc,
};
diff --git a/sys/dev/sound/pcm/ac97.h b/sys/dev/sound/pcm/ac97.h
index 0697cea..1305424 100644
--- a/sys/dev/sound/pcm/ac97.h
+++ b/sys/dev/sound/pcm/ac97.h
@@ -75,4 +75,6 @@ struct ac97_info *ac97_create(device_t dev, void *devinfo, ac97_init *init,
void ac97_destroy(struct ac97_info *codec);
int ac97_setrate(struct ac97_info *codec, int which, int rate);
int ac97_setextmode(struct ac97_info *codec, u_int16_t mode);
+u_int16_t ac97_getextmode(struct ac97_info *codec);
+u_int16_t ac97_getextcaps(struct ac97_info *codec);
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
index e684218..2be774c 100644
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -43,7 +43,6 @@ static void buf_clear(snd_dbuf *b, u_int32_t fmt, int length);
static void chn_dmaupdate(pcm_channel *c);
static void chn_wrintr(pcm_channel *c);
static void chn_rdintr(pcm_channel *c);
-static u_int32_t chn_start(pcm_channel *c);
static int chn_buildfeeder(pcm_channel *c);
/*
* SOUND OUTPUT
@@ -489,7 +488,7 @@ chn_write(pcm_channel *c, struct uio *buf)
/* Start playing if not yet. */
if (!b->dl)
- chn_start(c);
+ chn_start(c, 0);
if (ret == 0) {
count = hz;
@@ -758,7 +757,7 @@ chn_read(pcm_channel *c, struct uio *buf)
/* Start capturing if not yet. */
if ((!bs->rl || !b->rl) && !b->dl)
- chn_start(c);
+ chn_start(c, 0);
if (!(c->flags & CHN_F_NBIO)) {
count = hz;
@@ -815,23 +814,23 @@ chn_intr(pcm_channel *c)
}
u_int32_t
-chn_start(pcm_channel *c)
+chn_start(pcm_channel *c, int force)
{
u_int32_t r, s;
snd_dbuf *b = &c->buffer;
r = 0;
s = spltty();
- if (b->dl == 0 && !(c->flags & (CHN_F_MAPPED | CHN_F_NOTRIGGER))) {
+ if (b->dl == 0 && !(c->flags & CHN_F_NOTRIGGER)) {
if (c->direction == PCMDIR_PLAY) {
- /* Fill up the DMA buffer. */
- while (chn_wrfeed(c) > 0);
- if (b->rl >= b->blksz)
+ if (!(c->flags & CHN_F_MAPPED))
+ while (chn_wrfeed(c) > 0); /* Fill up the DMA buffer. */
+ if (force || (b->rl >= b->blksz))
r = CHN_F_TRIGGERED;
} else {
- /* Suck up the DMA buffer. */
- while (chn_rdfeed(c) > 0);
- if (b->fl >= b->blksz)
+ if (!(c->flags & CHN_F_MAPPED))
+ while (chn_rdfeed(c) > 0); /* Suck up the DMA buffer. */
+ if (force || (b->fl >= b->blksz))
r = CHN_F_TRIGGERED;
}
c->flags |= r;
@@ -1021,7 +1020,7 @@ chn_poll(pcm_channel *c, int ev, struct proc *p)
while (chn_rdfeed(c) > 0);
}
if (!b->dl)
- chn_start(c);
+ chn_start(c, 1);
}
ret = 0;
if (chn_polltrigger(c) && chn_pollreset(c))
@@ -1111,7 +1110,6 @@ fmtvalid(u_int32_t fmt, u_int32_t *fmtlist)
for (i = 0; fmtlist[i]; i++)
if (fmt == fmtlist[i])
return 1;
-
return 0;
}
@@ -1122,6 +1120,8 @@ chn_reset(pcm_channel *c, u_int32_t fmt)
chn_abort(c);
c->flags &= CHN_F_RESET;
+ if (c->reset)
+ c->reset(c->devinfo);
r = chn_setblocksize(c, CHN_2NDBUFBLKNUM, CHN_2NDBUFBLKSIZE);
if (r)
return r;
@@ -1134,6 +1134,8 @@ chn_reset(pcm_channel *c, u_int32_t fmt)
r = chn_setvolume(c, 100, 100);
}
chn_resetbuf(c);
+ if (c->resetdone)
+ c->resetdone(c->devinfo);
/* c->flags |= CHN_F_INIT; */
return 0;
}
diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h
index 26857a6..fa1173b 100644
--- a/sys/dev/sound/pcm/channel.h
+++ b/sys/dev/sound/pcm/channel.h
@@ -29,6 +29,7 @@
int chn_reinit(pcm_channel *c);
int chn_write(pcm_channel *c, struct uio *buf);
int chn_read(pcm_channel *c, struct uio *buf);
+u_int32_t chn_start(pcm_channel *c, int force);
int chn_sync(pcm_channel *c, int threshold);
int chn_flush(pcm_channel *c);
int chn_poll(pcm_channel *c, int ev, struct proc *p);
diff --git a/sys/dev/sound/pcm/datatypes.h b/sys/dev/sound/pcm/datatypes.h
index 3dcf670..6b4c01b 100644
--- a/sys/dev/sound/pcm/datatypes.h
+++ b/sys/dev/sound/pcm/datatypes.h
@@ -37,11 +37,13 @@ typedef int (mix_set_t)(snd_mixer *m, unsigned dev, unsigned left, unsigned righ
typedef int (mix_recsrc_t)(snd_mixer *m, u_int32_t src);
typedef int (mix_init_t)(snd_mixer *m);
typedef int (mix_uninit_t)(snd_mixer *m);
+typedef int (mix_reinit_t)(snd_mixer *m);
struct _snd_mixer {
char name[64];
mix_init_t *init;
mix_uninit_t *uninit;
+ mix_uninit_t *reinit;
mix_set_t *set;
mix_recsrc_t *setrecsrc;
@@ -117,6 +119,8 @@ typedef int (pcmchan_trigger_t)(void *data, int go);
typedef int (pcmchan_getptr_t)(void *data);
typedef int (pcmchan_free_t)(void *data);
typedef pcmchan_caps *(pcmchan_getcaps_t)(void *data);
+typedef int (pcmchan_reset_t)(void *data);
+typedef int (pcmchan_resetdone_t)(void *data);
struct _pcm_channel {
pcmchan_init_t *init;
@@ -128,8 +132,8 @@ struct _pcm_channel {
pcmchan_getptr_t *getptr;
pcmchan_getcaps_t *getcaps;
pcmchan_free_t *free;
- void *nop1;
- void *nop2;
+ pcmchan_reset_t *reset;
+ pcmchan_resetdone_t *resetdone;
void *nop3;
void *nop4;
void *nop5;
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c
index 545c9a6..47f141f 100644
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -121,12 +121,19 @@ mixer_reinit(device_t dev)
int i;
snddev_info *d = device_get_softc(dev);
if (d == NULL) return -1;
- if (d->mixer.init != NULL && d->mixer.init(&d->mixer) == 0) {
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- mixer_set(d, i, d->mixer.level[i]);
- mixer_setrecsrc(d, d->mixer.recsrc);
- return 0;
- } else return -1;
+
+ if (d->mixer.reinit != NULL)
+ i = d->mixer.reinit(&d->mixer);
+ else if (d->mixer.init != NULL)
+ i = d->mixer.init(&d->mixer);
+ else
+ i = 0;
+ if (i)
+ return i;
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
+ mixer_set(d, i, d->mixer.level[i]);
+ mixer_setrecsrc(d, d->mixer.recsrc);
+ return 0;
}
int
OpenPOWER on IntegriCloud