1 /*- 2 * Copyright (c) 2010 Hans Petter Selasky. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * 25 * $FreeBSD: head/sys/dev/usb/gadget/g_audio.c 269664 2014-08-07 12:47:25Z hselasky $ 26 */ 27 28 /* 29 * USB audio specs: http://www.usb.org/developers/devclass_docs/audio10.pdf 30 * http://www.usb.org/developers/devclass_docs/frmts10.pdf 31 * http://www.usb.org/developers/devclass_docs/termt10.pdf 32 */ 33 34 #include <sys/stdint.h> 35 #include <sys/queue.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/bus.h> 39 #include <sys/linker_set.h> 40 #include <sys/module.h> 41 #include <sys/lock.h> 42 #include <sys/condvar.h> 43 #include <sys/sysctl.h> 44 #include <sys/unistd.h> 45 #include <sys/callout.h> 46 #include <sys/malloc.h> 47 #include <sys/priv.h> 48 49 #include <bus/u4b/usb.h> 50 #include <bus/u4b/usb_cdc.h> 51 #include <bus/u4b/usbdi.h> 52 #include <bus/u4b/usbdi_util.h> 53 #include <bus/u4b/usbhid.h> 54 #include "usb_if.h" 55 56 #define USB_DEBUG_VAR g_audio_debug 57 #include <bus/u4b/usb_debug.h> 58 59 #include <bus/u4b/gadget/g_audio.h> 60 61 enum { 62 G_AUDIO_ISOC0_RD, 63 G_AUDIO_ISOC1_RD, 64 G_AUDIO_ISOC0_WR, 65 G_AUDIO_ISOC1_WR, 66 G_AUDIO_N_TRANSFER, 67 }; 68 69 struct g_audio_softc { 70 struct lock sc_lock; 71 struct usb_callout sc_callout; 72 struct usb_callout sc_watchdog; 73 struct usb_xfer *sc_xfer[G_AUDIO_N_TRANSFER]; 74 75 int sc_mode; 76 int sc_pattern_len; 77 int sc_throughput; 78 int sc_tx_interval; 79 int sc_state; 80 int sc_noise_rem; 81 82 int8_t sc_pattern[G_AUDIO_MAX_STRLEN]; 83 84 uint16_t sc_data_len[2][G_AUDIO_FRAMES]; 85 86 int16_t sc_data_buf[2][G_AUDIO_BUFSIZE / 2]; 87 88 uint8_t sc_volume_setting[32]; 89 uint8_t sc_volume_limit[32]; 90 uint8_t sc_sample_rate[32]; 91 }; 92 93 static SYSCTL_NODE(_hw_usb, OID_AUTO, g_audio, CTLFLAG_RW, 0, "USB audio gadget"); 94 95 #ifdef USB_DEBUG 96 static int g_audio_debug = 0; 97 98 SYSCTL_INT(_hw_usb_g_audio, OID_AUTO, debug, CTLFLAG_RW, 99 &g_audio_debug, 0, "Debug level"); 100 #endif 101 102 static int g_audio_mode = 0; 103 104 SYSCTL_INT(_hw_usb_g_audio, OID_AUTO, mode, CTLFLAG_RW, 105 &g_audio_mode, 0, "Mode selection"); 106 107 static int g_audio_pattern_interval = 1000; 108 109 SYSCTL_INT(_hw_usb_g_audio, OID_AUTO, pattern_interval, CTLFLAG_RW, 110 &g_audio_pattern_interval, 0, "Pattern interval in milliseconds"); 111 112 static char g_audio_pattern_data[G_AUDIO_MAX_STRLEN]; 113 114 SYSCTL_STRING(_hw_usb_g_audio, OID_AUTO, pattern, CTLFLAG_RW, 115 &g_audio_pattern_data, sizeof(g_audio_pattern_data), "Data pattern"); 116 117 static int g_audio_throughput; 118 119 SYSCTL_INT(_hw_usb_g_audio, OID_AUTO, throughput, CTLFLAG_RD, 120 &g_audio_throughput, sizeof(g_audio_throughput), "Throughput in bytes per second"); 121 122 static device_probe_t g_audio_probe; 123 static device_attach_t g_audio_attach; 124 static device_detach_t g_audio_detach; 125 static usb_handle_request_t g_audio_handle_request; 126 127 static usb_callback_t g_audio_isoc_read_callback; 128 static usb_callback_t g_audio_isoc_write_callback; 129 130 static devclass_t g_audio_devclass; 131 132 static void g_audio_watchdog(void *arg); 133 static void g_audio_timeout(void *arg); 134 135 static device_method_t g_audio_methods[] = { 136 /* USB interface */ 137 DEVMETHOD(usb_handle_request, g_audio_handle_request), 138 139 /* Device interface */ 140 DEVMETHOD(device_probe, g_audio_probe), 141 DEVMETHOD(device_attach, g_audio_attach), 142 DEVMETHOD(device_detach, g_audio_detach), 143 144 DEVMETHOD_END 145 }; 146 147 static driver_t g_audio_driver = { 148 .name = "g_audio", 149 .methods = g_audio_methods, 150 .size = sizeof(struct g_audio_softc), 151 }; 152 153 DRIVER_MODULE(g_audio, uhub, g_audio_driver, g_audio_devclass, NULL, NULL); 154 MODULE_DEPEND(g_audio, usb, 1, 1, 1); 155 156 static const struct usb_config g_audio_config[G_AUDIO_N_TRANSFER] = { 157 158 [G_AUDIO_ISOC0_RD] = { 159 .type = UE_ISOCHRONOUS, 160 .endpoint = UE_ADDR_ANY, 161 .direction = UE_DIR_RX, 162 .flags = {.ext_buffer = 1,.pipe_bof = 1,.short_xfer_ok = 1,}, 163 .bufsize = G_AUDIO_BUFSIZE, 164 .callback = &g_audio_isoc_read_callback, 165 .frames = G_AUDIO_FRAMES, 166 .usb_mode = USB_MODE_DEVICE, 167 .if_index = 1, 168 }, 169 170 [G_AUDIO_ISOC1_RD] = { 171 .type = UE_ISOCHRONOUS, 172 .endpoint = UE_ADDR_ANY, 173 .direction = UE_DIR_RX, 174 .flags = {.ext_buffer = 1,.pipe_bof = 1,.short_xfer_ok = 1,}, 175 .bufsize = G_AUDIO_BUFSIZE, 176 .callback = &g_audio_isoc_read_callback, 177 .frames = G_AUDIO_FRAMES, 178 .usb_mode = USB_MODE_DEVICE, 179 .if_index = 1, 180 }, 181 182 [G_AUDIO_ISOC0_WR] = { 183 .type = UE_ISOCHRONOUS, 184 .endpoint = UE_ADDR_ANY, 185 .direction = UE_DIR_TX, 186 .flags = {.ext_buffer = 1,.pipe_bof = 1,}, 187 .bufsize = G_AUDIO_BUFSIZE, 188 .callback = &g_audio_isoc_write_callback, 189 .frames = G_AUDIO_FRAMES, 190 .usb_mode = USB_MODE_DEVICE, 191 .if_index = 2, 192 }, 193 194 [G_AUDIO_ISOC1_WR] = { 195 .type = UE_ISOCHRONOUS, 196 .endpoint = UE_ADDR_ANY, 197 .direction = UE_DIR_TX, 198 .flags = {.ext_buffer = 1,.pipe_bof = 1,}, 199 .bufsize = G_AUDIO_BUFSIZE, 200 .callback = &g_audio_isoc_write_callback, 201 .frames = G_AUDIO_FRAMES, 202 .usb_mode = USB_MODE_DEVICE, 203 .if_index = 2, 204 }, 205 }; 206 207 static void 208 g_audio_timeout_reset(struct g_audio_softc *sc) 209 { 210 int i = g_audio_pattern_interval; 211 212 sc->sc_tx_interval = i; 213 214 if (i <= 0) 215 i = 1; 216 else if (i > 1023) 217 i = 1023; 218 219 i = USB_MS_TO_TICKS(i); 220 221 usb_callout_reset(&sc->sc_callout, i, &g_audio_timeout, sc); 222 } 223 224 static void 225 g_audio_timeout(void *arg) 226 { 227 struct g_audio_softc *sc = arg; 228 229 sc->sc_mode = g_audio_mode; 230 231 memcpy(sc->sc_pattern, g_audio_pattern_data, sizeof(sc->sc_pattern)); 232 233 sc->sc_pattern[G_AUDIO_MAX_STRLEN - 1] = 0; 234 235 sc->sc_pattern_len = strlen(sc->sc_pattern); 236 237 if (sc->sc_mode != G_AUDIO_MODE_LOOP) { 238 usbd_transfer_start(sc->sc_xfer[G_AUDIO_ISOC0_WR]); 239 usbd_transfer_start(sc->sc_xfer[G_AUDIO_ISOC1_WR]); 240 } 241 g_audio_timeout_reset(sc); 242 } 243 244 static void 245 g_audio_watchdog_reset(struct g_audio_softc *sc) 246 { 247 usb_callout_reset(&sc->sc_watchdog, hz, &g_audio_watchdog, sc); 248 } 249 250 static void 251 g_audio_watchdog(void *arg) 252 { 253 struct g_audio_softc *sc = arg; 254 int i; 255 256 i = sc->sc_throughput; 257 258 sc->sc_throughput = 0; 259 260 g_audio_throughput = i; 261 262 g_audio_watchdog_reset(sc); 263 } 264 265 static int 266 g_audio_probe(device_t dev) 267 { 268 struct usb_attach_arg *uaa = device_get_ivars(dev); 269 270 DPRINTFN(11, "\n"); 271 272 if (uaa->usb_mode != USB_MODE_DEVICE) 273 return (ENXIO); 274 275 if ((uaa->info.bInterfaceClass == UICLASS_AUDIO) && 276 (uaa->info.bInterfaceSubClass == UISUBCLASS_AUDIOCONTROL)) 277 return (0); 278 279 return (ENXIO); 280 } 281 282 static int 283 g_audio_attach(device_t dev) 284 { 285 struct g_audio_softc *sc = device_get_softc(dev); 286 struct usb_attach_arg *uaa = device_get_ivars(dev); 287 int error; 288 int i; 289 uint8_t iface_index[3]; 290 291 DPRINTFN(11, "\n"); 292 293 device_set_usb_desc(dev); 294 295 lockinit(&sc->sc_lock, "g_audio", 0, 0); 296 297 usb_callout_init_mtx(&sc->sc_callout, &sc->sc_lock, 0); 298 usb_callout_init_mtx(&sc->sc_watchdog, &sc->sc_lock, 0); 299 300 sc->sc_mode = G_AUDIO_MODE_SILENT; 301 302 sc->sc_noise_rem = 1; 303 304 for (i = 0; i != G_AUDIO_FRAMES; i++) { 305 sc->sc_data_len[0][i] = G_AUDIO_BUFSIZE / G_AUDIO_FRAMES; 306 sc->sc_data_len[1][i] = G_AUDIO_BUFSIZE / G_AUDIO_FRAMES; 307 } 308 309 iface_index[0] = uaa->info.bIfaceIndex; 310 iface_index[1] = uaa->info.bIfaceIndex + 1; 311 iface_index[2] = uaa->info.bIfaceIndex + 2; 312 313 error = usbd_set_alt_interface_index(uaa->device, iface_index[1], 1); 314 if (error) { 315 DPRINTF("alt iface setting error=%s\n", usbd_errstr(error)); 316 goto detach; 317 } 318 error = usbd_set_alt_interface_index(uaa->device, iface_index[2], 1); 319 if (error) { 320 DPRINTF("alt iface setting error=%s\n", usbd_errstr(error)); 321 goto detach; 322 } 323 error = usbd_transfer_setup(uaa->device, 324 iface_index, sc->sc_xfer, g_audio_config, 325 G_AUDIO_N_TRANSFER, sc, &sc->sc_lock); 326 327 if (error) { 328 DPRINTF("error=%s\n", usbd_errstr(error)); 329 goto detach; 330 } 331 usbd_set_parent_iface(uaa->device, iface_index[1], iface_index[0]); 332 usbd_set_parent_iface(uaa->device, iface_index[2], iface_index[0]); 333 334 lockmgr(&sc->sc_lock, LK_EXCLUSIVE); 335 336 usbd_transfer_start(sc->sc_xfer[G_AUDIO_ISOC0_RD]); 337 usbd_transfer_start(sc->sc_xfer[G_AUDIO_ISOC1_RD]); 338 339 usbd_transfer_start(sc->sc_xfer[G_AUDIO_ISOC0_WR]); 340 usbd_transfer_start(sc->sc_xfer[G_AUDIO_ISOC1_WR]); 341 342 g_audio_timeout_reset(sc); 343 344 g_audio_watchdog_reset(sc); 345 346 lockmgr(&sc->sc_lock, LK_RELEASE); 347 348 return (0); /* success */ 349 350 detach: 351 g_audio_detach(dev); 352 353 return (ENXIO); /* error */ 354 } 355 356 static int 357 g_audio_detach(device_t dev) 358 { 359 struct g_audio_softc *sc = device_get_softc(dev); 360 361 DPRINTF("\n"); 362 363 lockmgr(&sc->sc_lock, LK_EXCLUSIVE); 364 usb_callout_stop(&sc->sc_callout); 365 usb_callout_stop(&sc->sc_watchdog); 366 lockmgr(&sc->sc_lock, LK_RELEASE); 367 368 usbd_transfer_unsetup(sc->sc_xfer, G_AUDIO_N_TRANSFER); 369 370 usb_callout_drain(&sc->sc_callout); 371 usb_callout_drain(&sc->sc_watchdog); 372 373 lockuninit(&sc->sc_lock); 374 375 return (0); 376 } 377 378 379 static int32_t 380 g_noise(struct g_audio_softc *sc) 381 { 382 uint32_t temp; 383 const uint32_t prime = 0xFFFF1D; 384 385 if (sc->sc_noise_rem & 1) { 386 sc->sc_noise_rem += prime; 387 } 388 sc->sc_noise_rem /= 2; 389 390 temp = sc->sc_noise_rem; 391 392 /* unsigned to signed conversion */ 393 394 temp ^= 0x800000; 395 if (temp & 0x800000) { 396 temp |= (-0x800000); 397 } 398 return temp; 399 } 400 401 static void 402 g_audio_make_samples(struct g_audio_softc *sc, int16_t *ptr, int samples) 403 { 404 int i; 405 int j; 406 407 for (i = 0; i != samples; i++) { 408 409 j = g_noise(sc); 410 411 if ((sc->sc_state < 0) || (sc->sc_state >= sc->sc_pattern_len)) 412 sc->sc_state = 0; 413 414 if (sc->sc_pattern_len != 0) { 415 j = (j * sc->sc_pattern[sc->sc_state]) >> 16; 416 sc->sc_state++; 417 } 418 *ptr++ = j / 256; 419 *ptr++ = j / 256; 420 } 421 } 422 423 static void 424 g_audio_isoc_write_callback(struct usb_xfer *xfer, usb_error_t error) 425 { 426 struct g_audio_softc *sc = usbd_xfer_softc(xfer); 427 int actlen; 428 int aframes; 429 int nr = (xfer == sc->sc_xfer[G_AUDIO_ISOC0_WR]) ? 0 : 1; 430 int16_t *ptr; 431 int i; 432 433 usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL); 434 435 DPRINTF("st=%d aframes=%d actlen=%d bytes\n", 436 USB_GET_STATE(xfer), aframes, actlen); 437 438 switch (USB_GET_STATE(xfer)) { 439 case USB_ST_TRANSFERRED: 440 441 sc->sc_throughput += actlen; 442 443 if (sc->sc_mode == G_AUDIO_MODE_LOOP) 444 break; /* sync with RX */ 445 446 case USB_ST_SETUP: 447 tr_setup: 448 449 ptr = sc->sc_data_buf[nr]; 450 451 if (sc->sc_mode == G_AUDIO_MODE_PATTERN) { 452 453 for (i = 0; i != G_AUDIO_FRAMES; i++) { 454 455 usbd_xfer_set_frame_data(xfer, i, ptr, sc->sc_data_len[nr][i]); 456 457 g_audio_make_samples(sc, ptr, (G_AUDIO_BUFSIZE / G_AUDIO_FRAMES) / 2); 458 459 ptr += (G_AUDIO_BUFSIZE / G_AUDIO_FRAMES) / 2; 460 } 461 } else if (sc->sc_mode == G_AUDIO_MODE_LOOP) { 462 463 for (i = 0; i != G_AUDIO_FRAMES; i++) { 464 465 usbd_xfer_set_frame_data(xfer, i, ptr, sc->sc_data_len[nr][i] & ~3); 466 467 g_audio_make_samples(sc, ptr, sc->sc_data_len[nr][i] / 4); 468 469 ptr += (G_AUDIO_BUFSIZE / G_AUDIO_FRAMES) / 2; 470 } 471 } 472 break; 473 474 default: /* Error */ 475 DPRINTF("error=%s\n", usbd_errstr(error)); 476 477 if (error != USB_ERR_CANCELLED) { 478 /* try to clear stall first */ 479 usbd_xfer_set_stall(xfer); 480 goto tr_setup; 481 } 482 break; 483 } 484 } 485 486 static void 487 g_audio_isoc_read_callback(struct usb_xfer *xfer, usb_error_t error) 488 { 489 struct g_audio_softc *sc = usbd_xfer_softc(xfer); 490 int actlen; 491 int aframes; 492 int nr = (xfer == sc->sc_xfer[G_AUDIO_ISOC0_RD]) ? 0 : 1; 493 int16_t *ptr; 494 int i; 495 496 usbd_xfer_status(xfer, &actlen, NULL, &aframes, NULL); 497 498 DPRINTF("st=%d aframes=%d actlen=%d bytes\n", 499 USB_GET_STATE(xfer), aframes, actlen); 500 501 switch (USB_GET_STATE(xfer)) { 502 case USB_ST_TRANSFERRED: 503 504 sc->sc_throughput += actlen; 505 506 for (i = 0; i != G_AUDIO_FRAMES; i++) { 507 sc->sc_data_len[nr][i] = usbd_xfer_frame_len(xfer, i); 508 } 509 510 usbd_transfer_start(sc->sc_xfer[G_AUDIO_ISOC0_WR]); 511 usbd_transfer_start(sc->sc_xfer[G_AUDIO_ISOC1_WR]); 512 513 break; 514 515 case USB_ST_SETUP: 516 tr_setup: 517 ptr = sc->sc_data_buf[nr]; 518 519 for (i = 0; i != G_AUDIO_FRAMES; i++) { 520 521 usbd_xfer_set_frame_data(xfer, i, ptr, 522 G_AUDIO_BUFSIZE / G_AUDIO_FRAMES); 523 524 ptr += (G_AUDIO_BUFSIZE / G_AUDIO_FRAMES) / 2; 525 } 526 527 usbd_transfer_submit(xfer); 528 break; 529 530 default: /* Error */ 531 DPRINTF("error=%s\n", usbd_errstr(error)); 532 533 if (error != USB_ERR_CANCELLED) { 534 /* try to clear stall first */ 535 usbd_xfer_set_stall(xfer); 536 goto tr_setup; 537 } 538 break; 539 } 540 } 541 542 543 static int 544 g_audio_handle_request(device_t dev, 545 const void *preq, void **pptr, uint16_t *plen, 546 uint16_t offset, uint8_t *pstate) 547 { 548 struct g_audio_softc *sc = device_get_softc(dev); 549 const struct usb_device_request *req = preq; 550 uint8_t is_complete = *pstate; 551 552 if (!is_complete) { 553 if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) && 554 (req->bRequest == 0x82 /* get min */ )) { 555 556 if (offset == 0) { 557 USETW(sc->sc_volume_limit, 0); 558 *plen = 2; 559 *pptr = &sc->sc_volume_limit; 560 } else { 561 *plen = 0; 562 } 563 return (0); 564 } else if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) && 565 (req->bRequest == 0x83 /* get max */ )) { 566 567 if (offset == 0) { 568 USETW(sc->sc_volume_limit, 0x2000); 569 *plen = 2; 570 *pptr = &sc->sc_volume_limit; 571 } else { 572 *plen = 0; 573 } 574 return (0); 575 } else if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) && 576 (req->bRequest == 0x84 /* get residue */ )) { 577 578 if (offset == 0) { 579 USETW(sc->sc_volume_limit, 1); 580 *plen = 2; 581 *pptr = &sc->sc_volume_limit; 582 } else { 583 *plen = 0; 584 } 585 return (0); 586 } else if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) && 587 (req->bRequest == 0x81 /* get value */ )) { 588 589 if (offset == 0) { 590 USETW(sc->sc_volume_setting, 0x2000); 591 *plen = sizeof(sc->sc_volume_setting); 592 *pptr = &sc->sc_volume_setting; 593 } else { 594 *plen = 0; 595 } 596 return (0); 597 } else if ((req->bmRequestType == UT_WRITE_CLASS_INTERFACE) && 598 (req->bRequest == 0x01 /* set value */ )) { 599 600 if (offset == 0) { 601 *plen = sizeof(sc->sc_volume_setting); 602 *pptr = &sc->sc_volume_setting; 603 } else { 604 *plen = 0; 605 } 606 return (0); 607 } else if ((req->bmRequestType == UT_WRITE_CLASS_ENDPOINT) && 608 (req->bRequest == 0x01 /* set value */ )) { 609 610 if (offset == 0) { 611 *plen = sizeof(sc->sc_sample_rate); 612 *pptr = &sc->sc_sample_rate; 613 } else { 614 *plen = 0; 615 } 616 return (0); 617 } 618 } 619 return (ENXIO); /* use builtin handler */ 620 } 621