usbaudio.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /*
  2. * USB audio driver for Plan 9
  3. */
  4. #include <u.h>
  5. #include <libc.h>
  6. #include <thread.h>
  7. #include "usb.h"
  8. #include "usbaudio.h"
  9. #include "usbaudioctl.h"
  10. #define STACKSIZE 16*1024
  11. extern char* srvpost;
  12. char * mntpt;
  13. extern MasterVol masterplayvol; /* K.Okamoto */
  14. extern int mixerid; /* K.Okamoto */
  15. extern int selector; /* K.Okamoto */
  16. int vendor; /* K.Okamoto */
  17. int product; /* K.Okamoto */
  18. Channel *controlchan;
  19. char audstr[] = "Enabled 0x000101\n"; /* audio.control.0 */
  20. int defaultspeed[2] = {44100, 44100};
  21. extern FeatureAttr units[8][16]; /* K.Okamoto */
  22. extern int nunits[8];
  23. static void
  24. audio_endpoint(Device *d, int c, ulong csp, void *bb, int n)
  25. {
  26. int ifc;
  27. int dalt;
  28. byte *b = bb;
  29. if (c >= nelem(d->config)) {
  30. fprint(2, "Too many interfaces (%d of %d)\n",
  31. c, nelem(d->config));
  32. return;
  33. }
  34. dalt=csp>>24;
  35. ifc = csp>>16 & 0xff;
  36. switch(b[2]) {
  37. case 0x01:
  38. if (debug){
  39. fprint(2, "CS_ENDPOINT for attributes 0x%x, lockdelayunits %d, lockdelay %#ux, ",
  40. b[3], b[4], b[5] | (b[6]<<8));
  41. if (b[3] & has_setspeed)
  42. fprint(2, "has sampling-frequency control");
  43. else
  44. fprint(2, "does not have sampling-frequency control");
  45. if (b[3] & 0x1<<1)
  46. fprint(2, ", has pitch control");
  47. else
  48. fprint(2, ", does not have pitch control");
  49. if (b[3] & 0x1<<7)
  50. fprint(2, ", max packets only");
  51. fprint(2, "\n");
  52. }
  53. if (d->config[c] == nil)
  54. sysfatal("d->config[%d] == nil", c);
  55. if (d->config[c]->iface[ifc] == nil)
  56. sysfatal("d->config[%d]->iface[%d] == nil", c, ifc);
  57. if (d->config[c]->iface[ifc]->dalt[dalt] == nil)
  58. d->config[c]->iface[ifc]->dalt[dalt] = mallocz(sizeof(Dalt),1);
  59. if (d->config[c]->iface[ifc]->dalt[dalt]->devspec == nil)
  60. d->config[c]->iface[ifc]->dalt[dalt]->devspec= mallocz(sizeof(Audioalt),1);
  61. ((Audioalt*)d->config[c]->iface[ifc]->dalt[dalt]->devspec)->caps |= b[3];
  62. break;
  63. case 0x02:
  64. if (debug){
  65. fprint(2, "CS_INTERFACE FORMAT_TYPE %d, channels %d, subframesize %d, resolution %d, freqtype %d, ",
  66. b[3], b[4], b[5], b[6], b[7]);
  67. fprint(2, "freq0 %d, freq1 %d\n",
  68. b[8] | (b[9]<<8) | (b[10]<<16), b[11] | (b[12]<<8) | (b[13]<<16));
  69. }
  70. break;
  71. default:
  72. if (debug) pcs_raw("CS_INTERFACE", bb, n);
  73. }
  74. }
  75. void (*dprinter[])(Device *, int, ulong, void *b, int n) = {
  76. [STRING] pstring,
  77. [DEVICE] pdevice,
  78. [0x21] phid,
  79. [0x24] audio_interface,
  80. [0x25] audio_endpoint,
  81. };
  82. enum {
  83. None,
  84. Volumeset,
  85. Volumeget,
  86. Altset,
  87. Altget,
  88. Speedget,
  89. };
  90. void
  91. controlproc(void *)
  92. {
  93. /* Proc that looks after /dev/usb/%d/ctl */
  94. int i, nf;
  95. char *req, *args[8];
  96. Audiocontrol *c;
  97. long value[9];
  98. Channel *replchan;
  99. while(req = recvp(controlchan)){
  100. int rec;
  101. nf = tokenize(req, args, nelem(args));
  102. if (nf < 3)
  103. sysfatal("controlproc: not enough arguments");
  104. replchan = (Channel*)strtol(args[0], nil, 0);
  105. if (strcmp(args[2], "playback") == 0)
  106. rec = Play;
  107. else if (strcmp(args[2], "record") == 0)
  108. rec = Record;
  109. else{
  110. /* illegal request */
  111. if (debug) fprint(2, "%s must be record or playback", args[2]);
  112. if (replchan) chanprint(replchan, "%s must be record or playback", args[2]);
  113. free(req);
  114. continue;
  115. }
  116. c = nil;
  117. for (i = 0; i < Ncontrol; i++){
  118. c = &controls[rec][i];
  119. if (strcmp(args[1], c->name) == 0)
  120. break;
  121. }
  122. if (i == Ncontrol){
  123. if (debug) fprint(2, "Illegal control name: %s", args[1]);
  124. if (replchan) chanprint(replchan, "Illegal control name: %s", args[1]);
  125. }else if (!c->settable){
  126. if (debug & Dbginfo) fprint(2, "%s %s is not settable", args[1], args[2]);
  127. if (replchan)
  128. chanprint(replchan, "%s %s is not settable", args[1], args[2]);
  129. }else if (nf < 4){
  130. if (debug & Dbginfo) fprint(2, "insufficient arguments for %s %s",
  131. args[1], args[2]);
  132. if (replchan)
  133. chanprint(replchan, "insufficient arguments for %s %s",
  134. args[1], args[2]);
  135. }else if (ctlparse(args[3], c, value) < 0) {
  136. if (replchan)
  137. chanprint(replchan, "parse error in %s %s", args[1], args[2]);
  138. } else {
  139. if (debug & Dbginfo)
  140. fprint(2, "controlproc: setcontrol %s %s %s\n",
  141. rec?"in":"out", args[1], args[3]);
  142. if (rec == Play) { /* most messy part, K.Okamoto */
  143. if (vendor == 0xd8c && product== 0x6) { /* for C-Media CM-106/F chip */
  144. if (setcontrol(rec, args[1], value, 0) < 0){ /* units[masterPlayVol][0]: #13 Unit */
  145. if (replchan)
  146. chanprint(replchan, "setting %s %s failed", args[1], args[2]);
  147. }else{
  148. if (replchan) chanprint(replchan, "ok");
  149. }
  150. } else {
  151. if (setcontrol(rec, args[1], value, 0) < 0){ /* replace the '0' to another */
  152. if (replchan)
  153. chanprint(replchan, "setting %s %s failed", args[1], args[2]);
  154. }else{
  155. if (replchan) chanprint(replchan, "ok");
  156. }
  157. }
  158. } else
  159. if (rec == Record && !strcmp(args[1], "volume")) {
  160. if (vendor == 0xd8c && product== 0x6) { /* for C-Media CM-106/F chip */
  161. if (setcontrol(rec, args[1], value, 2) < 0){ /* units[LRRecVol][2]: #2 Unit */
  162. if (replchan)
  163. chanprint(replchan, "setting %s %s failed", args[1], args[2]);
  164. }else{
  165. if (replchan) chanprint(replchan, "ok");
  166. }
  167. }
  168. ctlevent();
  169. }
  170. }
  171. free(req);
  172. }
  173. }
  174. void
  175. buttonproc(void *) {
  176. int i, fd, b;
  177. char fname[64], err[32];
  178. byte buf[1];
  179. Audiocontrol *c, *cm;
  180. sprint(fname, "/dev/usb%d/%d/ep%ddata", ad->ctlrno, ad->id, buttonendpt);
  181. if (debug & Dbginfo) fprint(2, "buttonproc opening %s\n", fname);
  182. if ((fd = open(fname, OREAD)) < 0)
  183. sysfatal("Can't open %s: %r", fname);
  184. c = &controls[Play][Volume_control];
  185. cm = &controls[Play][Mute_control];
  186. if (vendor == 0xd8c && product== 0x6) /* for C-Media CM-106/F chip */
  187. cm->value[0] = units[masterPlayMute][0].value[0]; /* K.Okamoto, messy! */
  188. for (;;) {
  189. if ((b = read(fd, buf, 1)) < 0){
  190. rerrstr(err, sizeof err);
  191. if (strcmp(err, "interrupted") == 0){
  192. if (debug & Dbginfo) fprint(2, "read interrupted\n");
  193. continue;
  194. }
  195. sysfatal("read %s: %r", fname);
  196. }
  197. if (b == 0 || buf[0] == 0){
  198. continue;
  199. }else if (buf[0] == 1){ /* increase volume */
  200. c->chans = 0;
  201. c->value[0] += c->step;
  202. chanprint(controlchan, "0 volume playback %A", c);
  203. }else if (buf[0] == 2){ /* decrease volume */
  204. c->chans = 0;
  205. c->value[0] -= c->step;
  206. chanprint(controlchan, "0 volume playback %A", c);
  207. }else if (buf[0] == 4){ /* Play mute On/Off control K.Okamoto */
  208. cm->chans = 0;
  209. if (cm->value[0] == 0)
  210. cm->value[0] = 1;
  211. else
  212. cm->value[0] = 0;
  213. chanprint(controlchan, "0 mute playback %A", cm);
  214. }else if (buf[0] == 0x70){ /* Onkyo SE-U55X IrDA */
  215. // not implemented yet
  216. continue;
  217. }else if (debug & Dbginfo){
  218. fprint(2, "button");
  219. for (i = 0; i < b; i++)
  220. fprint(2, " %#2.2x", buf[i]);
  221. fprint(2, "\n");
  222. }
  223. }
  224. }
  225. void
  226. findendpoints(void)
  227. {
  228. Endpt *ep;
  229. int i, rec;
  230. for (i = 0; i < Nendpt; i++) {
  231. if ((ep = ad->ep[i]) == nil)
  232. continue;
  233. switch(ep->csp){
  234. default:
  235. break;
  236. case CSP(CL_AUDIO, 2, 0):
  237. if (ep->iface == nil)
  238. break;
  239. rec = (ep->addr & 0x80)?1:0;
  240. if (verbose)
  241. fprint(2, "%s on endpoint %d\n", rec?"Record":"Playback", i);
  242. endpt[rec] = i;
  243. interface[rec] = ep->iface->interface;
  244. break;
  245. case CSP(CL_HID, 0, 0):
  246. if (verbose)
  247. fprint(2, "Buttons on endpoint %d\n", i);
  248. buttonendpt = i;
  249. break;
  250. }
  251. }
  252. }
  253. void
  254. usage(void)
  255. {
  256. fprint(2, "usage: usbaudio [-V] [-v volume[%%]] [-m mountpoint] [-r recording device] [-s srvname] [ctrlno id]\n");
  257. threadexitsall("usage");
  258. }
  259. void
  260. threadmain(int argc, char **argv)
  261. {
  262. int ctlrno, id, i, j, sfd, select;
  263. long value[9];
  264. long volume[9];
  265. long mastervol; /* K.Okamoto */
  266. char buf[32], *p, line[256];
  267. ctlrno = -1;
  268. id = -1;
  269. volume[0] = 50; /* default volume is 50% */
  270. select = 4; /* Mixer input default, must be checked for other devices K.Okamoto */
  271. for (i = 0; i<9; i++) /* K.Okamoto */
  272. value[i] = 0;
  273. fmtinstall('A', Aconv);
  274. quotefmtinstall();
  275. mastervol = 0; /* K.Okamoto */
  276. ARGBEGIN{
  277. case 'V':
  278. verbose++;
  279. break;
  280. case 'd':
  281. debug = strtol(ARGF(), nil, 0);
  282. if (debug == -1) debugdebug++;
  283. verbose++;
  284. break;
  285. case 'v':
  286. mastervol = strtol(ARGF(), &p, 0);; /* K.Okamoto */
  287. for(i = 0; i < 9; i++)
  288. volume[i] = mastervol; /* K.Okamoto */
  289. break;
  290. case 'm':
  291. mntpt = ARGF();
  292. break;
  293. case 'r':
  294. select = atoi(ARGF());
  295. break;
  296. case 's':
  297. srvpost = ARGF();
  298. break;
  299. default:
  300. usage();
  301. }ARGEND
  302. switch (argc) {
  303. case 0:
  304. for (ctlrno = 0; ctlrno < 16; ctlrno++) {
  305. for (i = 1; i < 128; i++) {
  306. sprint(buf, "/dev/usb%d/%d/status", ctlrno, i);
  307. sfd = open(buf, OREAD);
  308. if (sfd < 0)
  309. break;
  310. if (read(sfd, line, strlen(audstr)) == strlen(audstr)
  311. && strncmp(audstr, line, strlen(audstr)) == 0) {
  312. id = i;
  313. goto found;
  314. }
  315. close(sfd);
  316. }
  317. }
  318. if (verbose) fprint(2, "No usb audio\n");
  319. threadexitsall("usbaudio not found");
  320. found:
  321. break;
  322. case 2:
  323. ctlrno = atoi(argv[0]);
  324. id = atoi(argv[1]);
  325. break;
  326. default:
  327. usage();
  328. }
  329. ad = opendev(ctlrno, id);
  330. if (describedevice(ad) < 0)
  331. sysfatal("describedevice");
  332. vendor = ad->vid;
  333. product = ad->did;
  334. for(i=0; i<ad->nconf; i++) {
  335. if (ad->config[i] == nil)
  336. ad->config[i] = mallocz(sizeof(*ad->config[i]),1);
  337. loadconfig(ad, i);
  338. }
  339. controlchan = chancreate(sizeof(char*), 8);
  340. findendpoints();
  341. if (endpt[Play] >= 0){
  342. if (vendor == 0xd8c && product == 0x6) { /* C-Media CM-106F chip K.Okamoto */
  343. if(findalt(Play, 8, 16, defaultspeed[Play]) < 0){
  344. if(findalt(Play, 8, 16, 48000) < 0)
  345. sysfatal("Can't configure playout for %d or %d Hz", defaultspeed[Play], 48000);
  346. fprint(2, "Warning, can't configure playout for %d Hz, configuring for %d Hz instead\n",
  347. defaultspeed[Play], 48000);
  348. defaultspeed[Play] = 48000;
  349. }
  350. } else {
  351. if(findalt(Play, 2, 16, defaultspeed[Play]) < 0){
  352. if(findalt(Play, 2, 16, 48000) < 0)
  353. sysfatal("Can't configure playout for %d or %d Hz", defaultspeed[Play], 48000);
  354. fprint(2, "Warning, can't configure playout for %d Hz, configuring for %d Hz instead\n",
  355. defaultspeed[Play], 48000);
  356. defaultspeed[Play] = 48000;
  357. }
  358. }
  359. /* K.Okamoto choose feature 4 (connected from Mixer) for Output to USB Stream */
  360. if (selector >0)
  361. if( setselector(select) == Undef)
  362. sysfatal("Failed to set selector\n");
  363. value[0] = 8; /* K.Okamoto */
  364. if (setcontrol(Play, "channels", value, featureid[Play]) == Undef)
  365. sysfatal("Can't set play channels\n");
  366. value[0] = 16;
  367. if (setcontrol(Play, "resolution", value, featureid[Play]) == Undef)
  368. sysfatal("Can't set play resolution\n");
  369. }
  370. if (endpt[Record] >= 0){
  371. if(findalt(Record, 2, 16, defaultspeed[Record]) < 0){
  372. if(findalt(Record, 2, 16, 48000) < 0)
  373. sysfatal("Can't configure record for %d or %d Hz", defaultspeed[Record], 48000);
  374. fprint(2, "Warning, can't configure record for %d Hz, configuring for %d Hz instead\n",
  375. defaultspeed[Record], 48000);
  376. defaultspeed[Record] = 48000;
  377. }
  378. /* K.Okamoto choose all the controls for Mixer inputs */
  379. if (mixerid >0)
  380. if (initmixer() == Undef) /* K.Okamoto, set all the channels alive on the mixer */
  381. sysfatal("Failed to set MIXER all live\n");
  382. value[0] = 2;
  383. if (setcontrol(Record, "channels", value, featureid[Record]) == Undef)
  384. sysfatal("Can't set record channels\n");
  385. value[0] = 16;
  386. if (setcontrol(Record, "resolution", value, featureid[Record]) == Undef)
  387. sysfatal("Can't set record resolution\n");
  388. }
  389. if(debugdebug) fprint(2, "\n=======Start of listing default values of feature units=======\n"); /*.K.Okamoto */
  390. getcontrols();
  391. if(debugdebug) fprint(2, "\n=======Start of setting values of feature units=======\n"); /*.K.Okamoto */
  392. value[0] = defaultspeed[Play];
  393. if (endpt[Play] >= 0 && setcontrol(Play, "speed", value, featureid[Play]) < 0)
  394. sysfatal("Can't set play speed\n");
  395. value[0] = defaultspeed[Record];
  396. if (endpt[Record] >= 0 && setcontrol(Record, "speed", value, featureid[Record]) < 0)
  397. sysfatal("Can't set record speed\n");
  398. /* here, 'i' is the n-th turn of multiple Units for this purpose,
  399. 'i' does not equals to Unit number itself */
  400. if (nunits[masterRecMute])
  401. for(i=0; i<nunits[masterRecMute]; i++) {
  402. value[0] = 0; /* set master Record Mute OFF K.Okamoto */
  403. setcontrol(Record, "mute", value, i);
  404. }
  405. if (nunits[masterPlayMute])
  406. for (i=0; i<nunits[masterPlayMute]; i++) {
  407. value[0] = 0; /* set master Play Mute OFF K.Okamoto */
  408. setcontrol(Play, "mute", value, i);
  409. }
  410. if (nunits[masterRecAGC])
  411. for (i=0; i<nunits[masterRecAGC]; i++) {
  412. value[0]=1; /* set AGC ON, K.Okamoto */
  413. setcontrol(Record, "agc", value, i); /* K.Okamoto */
  414. }
  415. if (nunits[LRRecVol])
  416. for (i=0; i<nunits[LRRecVol]; i++) {
  417. if (argc >=1 && *p == '%') {
  418. for (j = 0; j < 9; j++) {
  419. volume[j] = mastervol*(units[LRRecVol][i].max - units[LRRecVol][i].min)/100 + units[LRRecVol][i].min;
  420. if (debug & Dbgcontrol) fprint(2, "Unit#%d's , c->max, c->min= 0x%lx, 0x%lx\n",
  421. units[LRRecVol][i].id, units[LRRecVol][i].max, units[LRRecVol][i].min);
  422. if (debug & Dbgcontrol) fprint(2, "volume[%d] = 0x%lx\n", j, volume[j]);
  423. }
  424. } else {
  425. for (j = 0; j < 9; j++) {
  426. volume[j] = 50*(units[LRRecVol][i].max - units[LRRecVol][i].min)/100 +
  427. units[LRRecVol][i].min;
  428. if (debug & Dbgcontrol) fprint(2, "Unit#%d's , c->max, c->min= 0x%lx, 0x%lx\n",
  429. units[LRRecVol][i].id, units[LRRecVol][i].max, units[LRRecVol][i].min);
  430. if (debug & Dbgcontrol) fprint(2, "volume[%d] = 0x%lx\n", j, volume[j]);
  431. }
  432. }
  433. if (units[LRRecVol][i].settable)
  434. setcontrol(Record, "volume", volume, i);
  435. }
  436. if (nunits[LRPlayVol])
  437. for (i=0; i<nunits[LRPlayVol]; i++) {
  438. if (argc >=1 && *p == '%') {
  439. for (j = 0; j < 9; j++) {
  440. volume[j] = mastervol*(units[LRPlayVol][i].max - units[LRPlayVol][i].min)/100 +
  441. units[LRPlayVol][i].min;
  442. if (debug & Dbgcontrol) fprint(2, "Unit#%d's , c->max, c->min= 0x%lx, 0x%lx\n",
  443. units[LRPlayVol][i].id, units[LRPlayVol][i].max, units[LRPlayVol][i].min);
  444. if (debug & Dbgcontrol) fprint(2, "volume[%d] = 0x%lx\n", j, volume[j]);
  445. }
  446. } else {
  447. for (j = 0; j < 9; j++) {
  448. volume[j] = 50*(units[LRPlayVol][i].max - units[LRPlayVol][i].min)/100 +
  449. units[LRPlayVol][i].min;
  450. if (debug & Dbgcontrol) fprint(2, "Unit#%d's , c->max, c->min= 0x%lx, 0x%lx\n",
  451. units[LRPlayVol][i].id, units[LRPlayVol][i].max, units[LRPlayVol][i].min);
  452. if (debug & Dbgcontrol) fprint(2, "volume[%d] = 0x%lx\n", j, volume[j]);
  453. }
  454. }
  455. if (units[LRPlayVol][i].settable)
  456. setcontrol(Play, "volume", volume, i);
  457. }
  458. if (nunits[masterPlayVol])
  459. for (i=0; i<nunits[masterPlayVol]; i++) {
  460. if (argc >=1)
  461. volume[0] = mastervol*(masterplayvol.max - masterplayvol.min)/100+ masterplayvol.min;
  462. else
  463. volume[0] = 50*(masterplayvol.max - masterplayvol.min)/100+ masterplayvol.min;
  464. volume[1] = 0;
  465. if (debug & Dbgcontrol) fprint(2, "masterplayvol.max = %ld\n", masterplayvol.max);
  466. if (debug & Dbgcontrol) fprint(2, "masterplayvol.min = %ld\n", masterplayvol.min);
  467. if (debug & Dbgcontrol) fprint(2, "master Play volume[0] = %ld\n", volume[0]);
  468. if (units[masterPlayVol][i].settable)
  469. setcontrol(Play, "volume", volume, i);
  470. }
  471. if (buttonendpt > 0){
  472. sprint(buf, "ep %d bulk r 1 1", buttonendpt);
  473. if (debug) fprint(2, "sending `%s' to /dev/usb%d/%d/ctl\n", buf, ad->ctlrno, id);
  474. if (write(ad->ctl, buf, strlen(buf)) > 0)
  475. proccreate(buttonproc, nil, STACKSIZE);
  476. else
  477. fprint(2, "Could not configure button endpoint: %r\n");
  478. }
  479. proccreate(controlproc, nil, STACKSIZE);
  480. proccreate(serve, nil, STACKSIZE);
  481. threadexits(nil);
  482. }