Project

General

Profile

Submit #2682 » uaudio.patch

shamaz, 07/02/2014 09:37 AM

View differences:

sys/bus/u4b/audio/Makefile
KMOD= uaudio
SRCS= opt_bus.h opt_usb.h device_if.h bus_if.h usb_if.h usbdevs.h \
mixer_if.h feeder_if.h channel_if.h uaudio.c
mixer_if.h feeder_if.h channel_if.h uaudio.c uaudio_pcm.c
.include <bsd.kmod.mk>
sys/bus/u4b/audio/uaudio.c
};
struct uaudio_softc {
struct lock sc_lock;
sndlock_t lock;
struct sbuf sc_sndstat;
struct sndcard_func sc_sndcard_func;
......
struct usb_interface_descriptor *id;
device_t child;
lockinit(&sc->sc_lock, "uaudio", 0, 0);
sc->lock = snd_mtxcreate(device_get_nameunit(dev), "softc lock");
sc->sc_play_chan.priv_sc = sc;
sc->sc_rec_chan.priv_sc = sc;
sc->sc_udev = uaa->device;
......
sc->sc_sndstat_valid = 0;
umidi_detach(dev);
lockuninit(&sc->sc_lock);
snd_mtxfree(sc->lock);
return (0);
}
......
break;
}
#endif
/*
* KLUDGE:
* Add support at least for 2 channels
*/
if (ch->p_asf1d->bNrChannels == 2) format |= AFMT_STEREO;
ch->pcm_cap.fmtlist[0] = format;
ch->pcm_cap.fmtlist[1] = 0;
......
if (usbd_transfer_setup(sc->sc_udev, &sc->sc_mixer_iface_index,
sc->sc_mixer_xfer, uaudio_mixer_config, 1, sc,
&sc->sc_lock)) {
sc->lock)) {
DPRINTFN(0, "could not allocate USB "
"transfer for audio mixer!\n");
return (ENOMEM);
......
unsigned left, unsigned right)
{
struct uaudio_mixer_node *mc;
int chan;
for (mc = sc->sc_mixer_root; mc;
mc = mc->next) {
if (mc->ctl == type) {
if (mc->nchan == 2) {
/* set Right */
uaudio_mixer_ctl_set(sc, mc, 1, (int)(right * 255) / 100);
for (chan = 0; chan < mc->nchan; chan++) {
uaudio_mixer_ctl_set(sc, mc, chan,
(int)((chan == 0 ? left : right) * 255) / 100);
}
/* set Left or Mono */
uaudio_mixer_ctl_set(sc, mc, 0, (int)(left * 255) / 100);
}
}
}
......
return (0);
}
sndlock_t
uaudio_mixer_lock(struct snd_mixer *m)
{
struct uaudio_softc *sc = mix_getdevinfo(m);
return sc->lock;
}
DRIVER_MODULE(uaudio, uhub, uaudio_driver, uaudio_devclass, NULL, NULL);
MODULE_DEPEND(uaudio, usb, 1, 1, 1);
MODULE_DEPEND(uaudio, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
sys/bus/u4b/audio/uaudio.h
unsigned left, unsigned right);
extern uint32_t uaudio_mixer_setrecsrc(struct uaudio_softc *sc, uint32_t src);
extern sndlock_t uaudio_mixer_lock(struct snd_mixer *m);
int uaudio_get_vendor(device_t dev);
int uaudio_get_product(device_t dev);
int uaudio_get_release(device_t dev);
sys/bus/u4b/audio/uaudio_pcm.c
return (uaudio_chan_set_param_blocksize(data, blocksize));
}
#if 0
static int
ua_chan_setfragments(kobj_t obj, void *data, uint32_t blocksize, uint32_t blockcount)
{
return (uaudio_chan_set_param_fragments(data, blocksize, blockcount));
}
#endif
static int
ua_chan_trigger(kobj_t obj, void *data, int go)
......
return (uaudio_chan_getcaps(data));
}
#if 0
static struct pcmchan_matrix *
ua_chan_getmatrix(kobj_t obj, void *data, uint32_t format)
{
return (uaudio_chan_getmatrix(data, format));
}
#endif
static kobj_method_t ua_chan_methods[] = {
KOBJMETHOD(channel_init, ua_chan_init),
......
static int
ua_mixer_set(struct snd_mixer *m, unsigned type, unsigned left, unsigned right)
{
struct lock *lock = mixer_get_lock(m);
uint8_t do_unlock;
if (lockstatus(lock, curthread)) {
do_unlock = 0;
} else {
do_unlock = 1;
lockmgr(lock, LK_EXCLUSIVE);
}
sndlock_t lock = uaudio_mixer_lock(m);
snd_mtxlock(lock);
uaudio_mixer_set(mix_getdevinfo(m), type, left, right);
if (do_unlock) {
lockmgr(lock, LK_RELEASE);
}
snd_mtxunlock(lock);
return (left | (right << 8));
}
static uint32_t
ua_mixer_setrecsrc(struct snd_mixer *m, uint32_t src)
{
struct lock *lock = mixer_get_lock(m);
int retval;
uint8_t do_unlock;
if (lockstatus(lock, curthread)) {
do_unlock = 0;
} else {
do_unlock = 1;
lockmgr(lock, LK_EXCLUSIVE);
}
sndlock_t lock = uaudio_mixer_lock(m);
snd_mtxlock(lock);
retval = uaudio_mixer_setrecsrc(mix_getdevinfo(m), src);
if (do_unlock) {
lockmgr(lock, LK_RELEASE);
}
snd_mtxunlock(lock);
return (retval);
}
sys/dev/sound/pcm/channel.c
return r;
}
/*
* given a bufsz value, round it to a power of 2 in the min-max range
* XXX only works if min and max are powers of 2
*/
static int
round_bufsz(int bufsz, int min, int max)
static unsigned int
round_bufsz (unsigned int bufsz, unsigned int min, unsigned int max)
{
int tmp = min * 2;
KASSERT((min & (min-1)) == 0, ("min %d must be power of 2", min));
KASSERT((max & (max-1)) == 0, ("max %d must be power of 2", max));
while (tmp <= bufsz)
tmp <<= 1;
tmp >>= 1;
if (tmp > max)
tmp = max;
return tmp;
int pow=1, res;
if (bufsz < min) bufsz = min;
else if (bufsz > max) bufsz = max;
if (bufsz & (bufsz-1)) {
while (bufsz >> pow) pow++;
res = 1<<pow;
}
else res = bufsz;
if (res > max) return res>>1;
else return res;
}
/*
(3-3/3)