diff options
author | cg <cg@FreeBSD.org> | 2000-12-18 01:36:41 +0000 |
---|---|---|
committer | cg <cg@FreeBSD.org> | 2000-12-18 01:36:41 +0000 |
commit | 2fae4aec24ea4529882b3ec4cda45661ccd48ea8 (patch) | |
tree | e7e32573ed48df98bed54daa386c3520e959e951 /sys/dev/sound/pcm/mixer.c | |
parent | 1fd2c926a884cc824e7da7ee1a51dad72b1dec5b (diff) | |
download | FreeBSD-src-2fae4aec24ea4529882b3ec4cda45661ccd48ea8.zip FreeBSD-src-2fae4aec24ea4529882b3ec4cda45661ccd48ea8.tar.gz |
kobjify.
this gives us several benefits, including:
* easier extensibility- new optional methods can be added to
ac97/mixer/channel classes without having to fixup every driver.
* forward compatibility for drivers, provided no new mandatory methods are
added.
Diffstat (limited to 'sys/dev/sound/pcm/mixer.c')
-rw-r--r-- | sys/dev/sound/pcm/mixer.c | 249 |
1 files changed, 141 insertions, 108 deletions
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c index 47f141f..ddb161b 100644 --- a/sys/dev/sound/pcm/mixer.c +++ b/sys/dev/sound/pcm/mixer.c @@ -28,6 +28,10 @@ #include <dev/sound/pcm/sound.h> +#include "mixer_if.h" + +MALLOC_DEFINE(M_MIXER, "mixer", "mixer"); + static u_int16_t snd_mixerdefaults[SOUND_MIXER_NRDEVICES] = { [SOUND_MIXER_VOLUME] = 75, [SOUND_MIXER_BASS] = 50, @@ -45,73 +49,144 @@ static u_int16_t snd_mixerdefaults[SOUND_MIXER_NRDEVICES] = { }; static int -mixer_set(snddev_info *d, unsigned dev, unsigned lev) +mixer_set(snd_mixer *mixer, unsigned dev, unsigned lev) { - if (d == NULL || d->mixer.set == NULL) return -1; - if ((dev < SOUND_MIXER_NRDEVICES) && (d->mixer.devs & (1 << dev))) { - unsigned l = min((lev & 0x00ff), 100); - unsigned r = min(((lev & 0xff00) >> 8), 100); - int v = d->mixer.set(&d->mixer, dev, l, r); - if (v >= 0) d->mixer.level[dev] = l | (r << 8); - return 0; - } else return -1; + unsigned l, r; + int v; + + if ((dev >= SOUND_MIXER_NRDEVICES) || (0 == (mixer->devs & (1 << dev)))) + return -1; + + l = min((lev & 0x00ff), 100); + r = min(((lev & 0xff00) >> 8), 100); + + v = MIXER_SET(mixer, dev, l, r); + if (v < 0) + return -1; + + mixer->level[dev] = l | (r << 8); + return 0; } static int -mixer_get(snddev_info *d, int dev) +mixer_get(snd_mixer *mixer, int dev) { - if (d == NULL) return -1; - if (dev < SOUND_MIXER_NRDEVICES && (d->mixer.devs & (1 << dev))) - return d->mixer.level[dev]; + if ((dev < SOUND_MIXER_NRDEVICES) && (mixer->devs & (1 << dev))) + return mixer->level[dev]; else return -1; } static int -mixer_setrecsrc(snddev_info *d, u_int32_t src) +mixer_setrecsrc(snd_mixer *mixer, u_int32_t src) { - if (d == NULL || d->mixer.setrecsrc == NULL) return -1; - src &= d->mixer.recdevs; - if (src == 0) src = SOUND_MASK_MIC; - d->mixer.recsrc = d->mixer.setrecsrc(&d->mixer, src); + src &= mixer->recdevs; + if (src == 0) + src = SOUND_MASK_MIC; + mixer->recsrc = MIXER_SETRECSRC(mixer, src); return 0; } static int -mixer_getrecsrc(snddev_info *d) +mixer_getrecsrc(snd_mixer *mixer) +{ + return mixer->recsrc; +} + +void +mix_setdevs(snd_mixer *m, u_int32_t v) +{ + m->devs = v; +} + +void +mix_setrecdevs(snd_mixer *m, u_int32_t v) +{ + m->recdevs = v; +} + +u_int32_t +mix_getdevs(snd_mixer *m) +{ + return m->devs; +} + +u_int32_t +mix_getrecdevs(snd_mixer *m) +{ + return m->recdevs; +} + +void * +mix_getdevinfo(snd_mixer *m) { - if (d == NULL) return -1; - return d->mixer.recsrc; + return m->devinfo; } int -mixer_init(device_t dev, snd_mixer *m, void *devinfo) -{ - snddev_info *d = device_get_softc(dev); - if (d == NULL) return -1; - d->mixer = *m; - d->mixer.devinfo = devinfo; - bzero(&d->mixer.level, sizeof d->mixer.level); - if (d->mixer.init != NULL && d->mixer.init(&d->mixer) == 0) { - int i; - for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { - u_int16_t v = snd_mixerdefaults[i]; - mixer_set(d, i, v | (v << 8)); - } - mixer_setrecsrc(d, SOUND_MASK_MIC); - return 0; - } else return -1; +mixer_busy(snd_mixer *m, int busy) +{ + m->busy = busy; + return 0; +} + +int +mixer_isbusy(snd_mixer *m) +{ + return m->busy; +} + +int +mixer_init(device_t dev, kobj_class_t cls, void *devinfo) +{ + snddev_info *d; + snd_mixer *m; + u_int16_t v; + int i; + + d = device_get_softc(dev); + m = (snd_mixer *)kobj_create(cls, M_MIXER, M_WAITOK | M_ZERO); + + m->name = cls->name; + m->devinfo = devinfo; + + if (MIXER_INIT(m)) + goto bad; + + for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { + v = snd_mixerdefaults[i]; + mixer_set(m, i, v | (v << 8)); + } + + mixer_setrecsrc(m, SOUND_MASK_MIC); + + d->mixer = m; + + return 0; + +bad: kobj_delete((kobj_t)m, M_MIXER); + return -1; } int mixer_uninit(device_t dev) { int i; - snddev_info *d = device_get_softc(dev); - if (d == NULL) return -1; + snddev_info *d; + snd_mixer *m; + + d = device_get_softc(dev); + m = d->mixer; + for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) - mixer_set(d, i, 0); - mixer_setrecsrc(d, SOUND_MASK_MIC); - if (d->mixer.uninit != NULL) d->mixer.uninit(&d->mixer); + mixer_set(m, i, 0); + + mixer_setrecsrc(m, SOUND_MASK_MIC); + + MIXER_UNINIT(m); + + kobj_delete((kobj_t)m, M_MIXER); + d->mixer = NULL; + return 0; } @@ -119,20 +194,21 @@ int mixer_reinit(device_t dev) { int i; - snddev_info *d = device_get_softc(dev); - if (d == NULL) 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; + snddev_info *d; + snd_mixer *m; + + d = device_get_softc(dev); + m = d->mixer; + + i = MIXER_REINIT(m); 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); + mixer_set(m, i, m->level[i]); + + mixer_setrecsrc(m, m->recsrc); + return 0; } @@ -140,35 +216,37 @@ int mixer_ioctl(snddev_info *d, u_long cmd, caddr_t arg) { int ret, *arg_i = (int *)arg; + int v = -1, j = cmd & 0xff; + snd_mixer *m; - if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)) { - int j = cmd & 0xff; + m = d->mixer; - if (j == SOUND_MIXER_RECSRC) ret = mixer_setrecsrc(d, *arg_i); - else ret = mixer_set(d, j, *arg_i); + if ((cmd & MIXER_WRITE(0)) == MIXER_WRITE(0)) { + if (j == SOUND_MIXER_RECSRC) + ret = mixer_setrecsrc(m, *arg_i); + else + ret = mixer_set(m, j, *arg_i); return (ret == 0)? 0 : ENXIO; } if ((cmd & MIXER_READ(0)) == MIXER_READ(0)) { - int v = -1, j = cmd & 0xff; - switch (j) { case SOUND_MIXER_DEVMASK: case SOUND_MIXER_CAPS: case SOUND_MIXER_STEREODEVS: - v = d->mixer.devs; + v = m->devs; break; case SOUND_MIXER_RECMASK: - v = d->mixer.recdevs; + v = m->recdevs; break; case SOUND_MIXER_RECSRC: - v = mixer_getrecsrc(d); + v = mixer_getrecsrc(m); break; default: - v = mixer_get(d, j); + v = mixer_get(m, j); } *arg_i = v; return (v != -1)? 0 : ENXIO; @@ -176,51 +254,6 @@ mixer_ioctl(snddev_info *d, u_long cmd, caddr_t arg) return ENXIO; } -int -mixer_busy(snddev_info *d, int busy) -{ - if (d == NULL) return -1; - d->mixer.busy = busy; - return 0; -} - -int -mixer_isbusy(snddev_info *d) -{ - if (d == NULL) return -1; - return d->mixer.busy; -} - -void -mix_setdevs(snd_mixer *m, u_int32_t v) -{ - m->devs = v; -} - -void -mix_setrecdevs(snd_mixer *m, u_int32_t v) -{ - m->recdevs = v; -} - -u_int32_t -mix_getdevs(snd_mixer *m) -{ - return m->devs; -} - -u_int32_t -mix_getrecdevs(snd_mixer *m) -{ - return m->recdevs; -} - -void * -mix_getdevinfo(snd_mixer *m) -{ - return m->devinfo; -} - /* * The various mixers use a variety of bitmasks etc. The Voxware * driver had a very nice technique to describe a mixer and interface |