diff options
| author | cinap_lenrek <cinap_lenrek@localhost> | 2011-07-30 13:57:21 +0200 |
|---|---|---|
| committer | cinap_lenrek <cinap_lenrek@localhost> | 2011-07-30 13:57:21 +0200 |
| commit | 488add7e5e704480741d2ab10acc7e9a52c311a6 (patch) | |
| tree | 32feb5fc4aa534966ec160fd3983284b5aca4822 | |
| parent | a2a95b615e5fb4a4c8b9a710a79cd7c36d1ad16c (diff) | |
| download | plan9front-488add7e5e704480741d2ab10acc7e9a52c311a6.tar.xz | |
nusb: simple playback only audio driver
| -rw-r--r-- | sys/src/cmd/nusb/audio/audio.c | 118 | ||||
| -rw-r--r-- | sys/src/cmd/nusb/audio/mkfile | 18 |
2 files changed, 136 insertions, 0 deletions
diff --git a/sys/src/cmd/nusb/audio/audio.c b/sys/src/cmd/nusb/audio/audio.c new file mode 100644 index 000000000..0b1440321 --- /dev/null +++ b/sys/src/cmd/nusb/audio/audio.c @@ -0,0 +1,118 @@ +#include <u.h> +#include <libc.h> +#include <thread.h> +#include "usb.h" + +int audiofreq = 44100; +int audiochan = 2; +int audiores = 16; + +char validaltc[] = ""; + +void +parsedescr(Desc *dd) +{ + uchar *b; + int i; + + if(dd == nil || dd->iface == nil || dd->altc == nil) + return; + b = (uchar*)&dd->data; + if(Subclass(dd->iface->csp) != 2 || b[1] != 0x24 || b[2] != 0x02) + return; + if(b[4] != audiochan) + return; + if(b[6] != audiores) + return; + if(b[7] == 0){ + int minfreq, maxfreq; + + minfreq = b[8] | b[9]<<8 | b[10]<<16; + maxfreq = b[11] | b[12]<<8 | b[13]<<16; + if(minfreq > audiofreq || maxfreq < audiofreq) + return; + } else { + int freq; + + for(i=0; i<b[7]; i++){ + freq = b[8+3*i] | b[9+3*i]<<8 | b[10+3*i]<<16; + if(freq == audiofreq) + break; + } + if(i == b[7]) + return; + } + dd->altc->aux = validaltc; +} + +void +usage(void) +{ + fprint(2, "%s devid\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + Dev *d, *ed; + Usbdev *ud; + uchar b[4]; + Altc *a; + Ep *e; + int i; + + ARGBEGIN { + } ARGEND; + + if(argc == 0) + usage(); + + if((d = getdev(atoi(*argv))) == nil) + sysfatal("getdev: %r"); + if(configdev(d) < 0) + sysfatal("configdev: %r"); + + ud = d->usb; + + /* parse descriptors, mark valid altc */ + for(i = 0; i < nelem(ud->ddesc); i++) + parsedescr(ud->ddesc[i]); + + for(i = 0; i < nelem(ud->ep); i++){ + e = ud->ep[i]; + if(e && e->iface && e->iface->csp == CSP(Claudio, 2, 0) && e->dir == Eout) + goto Foundendp; + } + sysfatal("no endpoints found"); + return; + +Foundendp: + for(i = 0; i < nelem(e->iface->altc); i++){ + a = e->iface->altc[i]; + if(a && a->aux == validaltc) + goto Foundaltc; + } + sysfatal("no altc found"); + +Foundaltc: + if(usbcmd(d, Rh2d|Rstd|Riface, Rsetiface, i, e->iface->id, nil, 0) < 0) + sysfatal("usbcmd: set altc: %r"); + + b[0] = audiofreq; + b[1] = audiofreq >> 8; + b[2] = audiofreq >> 16; + if(usbcmd(d, Rh2d|Rclass|Rep, Rsetcur, 0x100, e->addr, b, 3) < 0) + fprint(2, "warning: set freq: %r"); + + if((ed = openep(d, e->id)) == nil) + sysfatal("openep: %r"); + devctl(ed, "pollival %d", 1); + devctl(ed, "samplesz %d", audiochan*audiores/8); + devctl(ed, "hz %d", audiofreq); + + /* rename endpoint to #u/audio */ + devctl(ed, "name audio"); + + exits(0); +} diff --git a/sys/src/cmd/nusb/audio/mkfile b/sys/src/cmd/nusb/audio/mkfile new file mode 100644 index 000000000..ab168e321 --- /dev/null +++ b/sys/src/cmd/nusb/audio/mkfile @@ -0,0 +1,18 @@ +</$objtype/mkfile + +TARG=audio +OFILES=audio.$O +HFILES=../lib/usb.h + +LIB=../lib/usb.a$O + +BIN=/$objtype/bin/nusb + +UPDATE=\ + mkfile\ + $HFILES\ + ${OFILES:%.$O=%.c}\ + +</sys/src/cmd/mkone +CFLAGS=-I../lib $CFLAGS + |
