1 /* 2 * Driver for USB Audio Device Class devices. 3 * Copyright (c) 2009-13 S.Zharski <imker@gmx.li> 4 * Distributed under the terms of the MIT license. 5 * 6 */ 7 8 9 #include "Device.h" 10 11 #include <kernel.h> 12 #include <usb/USB_audio.h> 13 14 #include "Driver.h" 15 #include "Settings.h" 16 17 18 Device::Device(usb_device device) 19 : 20 fStatus(B_ERROR), 21 fOpen(false), 22 fRemoved(false), 23 fDevice(device), 24 fNonBlocking(false), 25 fAudioControl(this), 26 fBuffersReadySem(-1) 27 { 28 const usb_device_descriptor* deviceDescriptor 29 = gUSBModule->get_device_descriptor(device); 30 31 if (deviceDescriptor == NULL) { 32 TRACE(ERR, "Error of getting USB device descriptor.\n"); 33 return; 34 } 35 36 fVendorID = deviceDescriptor->vendor_id; 37 fProductID = deviceDescriptor->product_id; 38 fUSBVersion = deviceDescriptor->usb_version; 39 40 fBuffersReadySem = create_sem(0, DRIVER_NAME "_buffers_ready"); 41 if (fBuffersReadySem < B_OK) { 42 TRACE(ERR, "Error of creating ready " 43 "buffers semaphore:%#010x\n", fBuffersReadySem); 44 return; 45 } 46 47 if (_SetupEndpoints() != B_OK) 48 return; 49 50 // must be set in derived class constructor 51 fStatus = B_OK; 52 } 53 54 55 Device::~Device() 56 { 57 for (Vector<Stream*>::Iterator I = fStreams.Begin(); 58 I != fStreams.End(); I++) 59 delete *I; 60 61 fStreams.MakeEmpty(); 62 63 if (fBuffersReadySem > B_OK) 64 delete_sem(fBuffersReadySem); 65 } 66 67 68 status_t 69 Device::Open(uint32 flags) 70 { 71 if (fOpen) 72 return B_BUSY; 73 if (fRemoved) 74 return B_ERROR; 75 76 status_t result = StartDevice(); 77 if (result != B_OK) 78 return result; 79 80 // TODO: are we need this??? 81 fNonBlocking = (flags & O_NONBLOCK) == O_NONBLOCK; 82 fOpen = true; 83 return result; 84 } 85 86 87 status_t 88 Device::Close() 89 { 90 if (fRemoved) { 91 fOpen = false; 92 return B_OK; 93 } 94 95 for (int i = 0; i < fStreams.Count(); i++) 96 fStreams[i]->Stop(); 97 98 fOpen = false; 99 100 return StopDevice(); 101 } 102 103 104 status_t 105 Device::Free() 106 { 107 return B_OK; 108 } 109 110 111 status_t 112 Device::Read(uint8* buffer, size_t* numBytes) 113 { 114 *numBytes = 0; 115 return B_IO_ERROR; 116 } 117 118 119 status_t 120 Device::Write(const uint8* buffer, size_t* numBytes) 121 { 122 *numBytes = 0; 123 return B_IO_ERROR; 124 } 125 126 127 status_t 128 Device::Control(uint32 op, void* buffer, size_t length) 129 { 130 switch (op) { 131 case B_MULTI_GET_DESCRIPTION: 132 { 133 multi_description description; 134 multi_channel_info channels[16]; 135 multi_channel_info* originalChannels; 136 137 if (user_memcpy(&description, buffer, sizeof(multi_description)) 138 != B_OK) 139 return B_BAD_ADDRESS; 140 141 originalChannels = description.channels; 142 description.channels = channels; 143 if (description.request_channel_count > 16) 144 description.request_channel_count = 16; 145 146 status_t status = _MultiGetDescription(&description); 147 if (status != B_OK) 148 return status; 149 150 description.channels = originalChannels; 151 if (user_memcpy(buffer, &description, sizeof(multi_description)) 152 != B_OK) 153 return B_BAD_ADDRESS; 154 return user_memcpy(originalChannels, channels, 155 sizeof(multi_channel_info) * description.request_channel_count); 156 } 157 case B_MULTI_GET_EVENT_INFO: 158 TRACE(ERR, "B_MULTI_GET_EVENT_INFO n/i\n"); 159 return B_ERROR; 160 161 case B_MULTI_SET_EVENT_INFO: 162 TRACE(ERR, "B_MULTI_SET_EVENT_INFO n/i\n"); 163 return B_ERROR; 164 165 case B_MULTI_GET_EVENT: 166 TRACE(ERR, "B_MULTI_GET_EVENT n/i\n"); 167 return B_ERROR; 168 169 case B_MULTI_GET_ENABLED_CHANNELS: 170 { 171 multi_channel_enable* data = (multi_channel_enable*)buffer; 172 multi_channel_enable enable; 173 uint32 enable_bits; 174 uchar* orig_enable_bits; 175 176 if (user_memcpy(&enable, data, sizeof(enable)) != B_OK 177 || !IS_USER_ADDRESS(enable.enable_bits)) { 178 return B_BAD_ADDRESS; 179 } 180 181 orig_enable_bits = enable.enable_bits; 182 enable.enable_bits = (uchar*)&enable_bits; 183 status_t status = _MultiGetEnabledChannels(&enable); 184 if (status != B_OK) 185 return status; 186 187 enable.enable_bits = orig_enable_bits; 188 if (user_memcpy(enable.enable_bits, &enable_bits, 189 sizeof(enable_bits)) != B_OK 190 || user_memcpy(buffer, &enable, 191 sizeof(multi_channel_enable)) != B_OK) { 192 return B_BAD_ADDRESS; 193 } 194 195 return B_OK; 196 } 197 case B_MULTI_SET_ENABLED_CHANNELS: 198 { 199 multi_channel_enable enable; 200 uint32 enable_bits; 201 uchar* orig_enable_bits; 202 203 if (user_memcpy(&enable, buffer, sizeof(enable)) != B_OK 204 || !IS_USER_ADDRESS(enable.enable_bits)) { 205 return B_BAD_ADDRESS; 206 } 207 208 orig_enable_bits = enable.enable_bits; 209 enable.enable_bits = (uchar*)&enable_bits; 210 status_t status = _MultiSetEnabledChannels(&enable); 211 if (status != B_OK) 212 return status; 213 214 enable.enable_bits = orig_enable_bits; 215 if (user_memcpy(enable.enable_bits, &enable_bits, 216 sizeof(enable_bits)) < B_OK 217 || user_memcpy(buffer, &enable, sizeof(multi_channel_enable)) 218 < B_OK) { 219 return B_BAD_ADDRESS; 220 } 221 222 return B_OK; 223 } 224 case B_MULTI_GET_GLOBAL_FORMAT: 225 { 226 multi_format_info info; 227 if (user_memcpy(&info, buffer, sizeof(multi_format_info)) != B_OK) 228 return B_BAD_ADDRESS; 229 230 status_t status = _MultiGetGlobalFormat(&info); 231 if (status != B_OK) 232 return B_OK; 233 if (user_memcpy(buffer, &info, sizeof(multi_format_info)) != B_OK) 234 return B_BAD_ADDRESS; 235 return B_OK; 236 } 237 case B_MULTI_SET_GLOBAL_FORMAT: 238 { 239 multi_format_info info; 240 if (user_memcpy(&info, buffer, sizeof(multi_format_info)) != B_OK) 241 return B_BAD_ADDRESS; 242 243 status_t status = _MultiSetGlobalFormat(&info); 244 if (status != B_OK) 245 return B_OK; 246 return user_memcpy(buffer, &info, sizeof(multi_format_info)); 247 } 248 case B_MULTI_GET_CHANNEL_FORMATS: 249 TRACE(ERR, "B_MULTI_GET_CHANNEL_FORMATS n/i\n"); 250 return B_ERROR; 251 252 case B_MULTI_SET_CHANNEL_FORMATS: 253 TRACE(ERR, "B_MULTI_SET_CHANNEL_FORMATS n/i\n"); 254 return B_ERROR; 255 256 case B_MULTI_GET_MIX: 257 return _MultiGetMix((multi_mix_value_info*)buffer); 258 259 case B_MULTI_SET_MIX: 260 return _MultiSetMix((multi_mix_value_info*)buffer); 261 262 case B_MULTI_LIST_MIX_CHANNELS: 263 TRACE(ERR, "B_MULTI_LIST_MIX_CHANNELS n/i\n"); 264 return B_ERROR; 265 266 case B_MULTI_LIST_MIX_CONTROLS: 267 { 268 multi_mix_control_info info; 269 multi_mix_control* original_controls; 270 size_t allocSize; 271 multi_mix_control *controls; 272 273 if (user_memcpy(&info, buffer, sizeof(multi_mix_control_info)) 274 != B_OK) { 275 return B_BAD_ADDRESS; 276 } 277 278 original_controls = info.controls; 279 allocSize = sizeof(multi_mix_control) * info.control_count; 280 controls = (multi_mix_control *)malloc(allocSize); 281 if (controls == NULL) 282 return B_NO_MEMORY; 283 284 if (!IS_USER_ADDRESS(info.controls) 285 || user_memcpy(controls, info.controls, allocSize) < B_OK) { 286 free(controls); 287 return B_BAD_ADDRESS; 288 } 289 info.controls = controls; 290 291 status_t status = _MultiListMixControls(&info); 292 if (status != B_OK) { 293 free(controls); 294 return status; 295 } 296 297 info.controls = original_controls; 298 status = user_memcpy(info.controls, controls, allocSize); 299 if (status == B_OK) { 300 status = user_memcpy(buffer, &info, 301 sizeof(multi_mix_control_info)); 302 } 303 if (status != B_OK) 304 status = B_BAD_ADDRESS; 305 free(controls); 306 return status; 307 } 308 case B_MULTI_LIST_MIX_CONNECTIONS: 309 TRACE(ERR, "B_MULTI_LIST_MIX_CONNECTIONS n/i\n"); 310 return B_ERROR; 311 312 case B_MULTI_GET_BUFFERS: 313 // Fill out the struct for the first time; doesn't start anything. 314 { 315 multi_buffer_list list; 316 if (user_memcpy(&list, buffer, sizeof(multi_buffer_list)) != B_OK) 317 return B_BAD_ADDRESS; 318 buffer_desc **original_playback_descs = list.playback_buffers; 319 buffer_desc **original_record_descs = list.record_buffers; 320 321 buffer_desc *playback_descs[list.request_playback_buffers]; 322 buffer_desc *record_descs[list.request_record_buffers]; 323 324 if (!IS_USER_ADDRESS(list.playback_buffers) 325 || user_memcpy(playback_descs, list.playback_buffers, 326 sizeof(buffer_desc*) * list.request_playback_buffers) 327 < B_OK 328 || !IS_USER_ADDRESS(list.record_buffers) 329 || user_memcpy(record_descs, list.record_buffers, 330 sizeof(buffer_desc*) * list.request_record_buffers) 331 < B_OK) { 332 return B_BAD_ADDRESS; 333 } 334 335 list.playback_buffers = playback_descs; 336 list.record_buffers = record_descs; 337 status_t status = _MultiGetBuffers(&list); 338 if (status != B_OK) 339 return status; 340 341 list.playback_buffers = original_playback_descs; 342 list.record_buffers = original_record_descs; 343 344 if (user_memcpy(buffer, &list, sizeof(multi_buffer_list)) < B_OK 345 || user_memcpy(original_playback_descs, playback_descs, 346 sizeof(buffer_desc*) * list.request_playback_buffers) 347 < B_OK 348 || user_memcpy(original_record_descs, record_descs, 349 sizeof(buffer_desc*) * list.request_record_buffers) 350 < B_OK) { 351 status = B_BAD_ADDRESS; 352 } 353 354 return status; 355 } 356 357 case B_MULTI_SET_BUFFERS: 358 // Set what buffers to use, if the driver supports soft buffers. 359 TRACE(ERR, "B_MULTI_SET_BUFFERS n/i\n"); 360 return B_ERROR; /* we do not support soft buffers */ 361 362 case B_MULTI_SET_START_TIME: 363 // When to actually start 364 TRACE(ERR, "B_MULTI_SET_START_TIME n/i\n"); 365 return B_ERROR; 366 367 case B_MULTI_BUFFER_EXCHANGE: 368 // stop and go are derived from this being called 369 return _MultiBufferExchange((multi_buffer_info*)buffer); 370 371 case B_MULTI_BUFFER_FORCE_STOP: 372 // force stop of playback, nothing in data 373 return _MultiBufferForceStop(); 374 375 default: 376 TRACE(ERR, "Unhandled IOCTL catched: %#010x\n", op); 377 } 378 379 return B_DEV_INVALID_IOCTL; 380 } 381 382 383 void 384 Device::Removed() 385 { 386 fRemoved = true; 387 388 for (int i = 0; i < fStreams.Count(); i++) 389 fStreams[i]->OnRemove(); 390 } 391 392 393 status_t 394 Device::SetupDevice(bool deviceReplugged) 395 { 396 return B_OK; 397 } 398 399 400 status_t 401 Device::CompareAndReattach(usb_device device) 402 { 403 const usb_device_descriptor* deviceDescriptor 404 = gUSBModule->get_device_descriptor(device); 405 406 if (deviceDescriptor == NULL) { 407 TRACE(ERR, "Error of getting USB device descriptor.\n"); 408 return B_ERROR; 409 } 410 411 if (deviceDescriptor->vendor_id != fVendorID 412 && deviceDescriptor->product_id != fProductID) 413 // this certainly isn't the same device 414 return B_BAD_VALUE; 415 416 // this is the same device that was replugged - clear the removed state, 417 // re- setup the endpoints and transfers and open the device if it was 418 // previously opened 419 fDevice = device; 420 fRemoved = false; 421 status_t result = _SetupEndpoints(); 422 if (result != B_OK) { 423 fRemoved = true; 424 return result; 425 } 426 427 // we need to setup hardware on device replug 428 result = SetupDevice(true); 429 if (result != B_OK) 430 return result; 431 432 if (fOpen) { 433 fOpen = false; 434 result = Open(fNonBlocking ? O_NONBLOCK : 0); 435 } 436 437 return result; 438 } 439 440 441 status_t 442 Device::_MultiGetDescription(multi_description* multiDescription) 443 { 444 multi_description Description; 445 if (user_memcpy(&Description, multiDescription, 446 sizeof(multi_description)) != B_OK) 447 return B_BAD_ADDRESS; 448 449 Description.interface_version = B_CURRENT_INTERFACE_VERSION; 450 Description.interface_minimum = B_CURRENT_INTERFACE_VERSION; 451 452 strlcpy(Description.friendly_name, "USB Audio", 453 sizeof(Description.friendly_name)); 454 455 strlcpy(Description.vendor_info, "S.Zharski", 456 sizeof(Description.vendor_info)); 457 458 Description.output_channel_count = 0; 459 Description.input_channel_count = 0; 460 Description.output_bus_channel_count = 0; 461 Description.input_bus_channel_count = 0; 462 Description.aux_bus_channel_count = 0; 463 464 Description.output_rates = 0; 465 Description.input_rates = 0; 466 467 Description.min_cvsr_rate = 0; 468 Description.max_cvsr_rate = 0; 469 470 Description.output_formats = 0; 471 Description.input_formats = 0; 472 Description.lock_sources = B_MULTI_LOCK_INTERNAL; 473 Description.timecode_sources = 0; 474 Description.interface_flags = 0; 475 Description.start_latency = 3000; 476 477 Description.control_panel[0] = '\0'; 478 479 Vector<_AudioControl*> USBTerminals; 480 481 // channels (USB I/O terminals) are already in fStreams 482 // in outputs->inputs order, use them. 483 for (int i = 0; i < fStreams.Count(); i++) { 484 uint8 id = fStreams[i]->TerminalLink(); 485 _AudioControl* control = fAudioControl.Find(id); 486 // if (control->SubType() == USB_AUDIO_AC_OUTPUT_TERMINAL) { 487 // if (control->SubType() == USB_AUDIO_AC_INPUT_TERMINAL) { 488 // USBTerminals.PushFront(control); 489 // fStreams[i]->GetFormatsAndRates(Description); 490 // } else 491 // if (control->SubType() == IDSInputTerminal) { 492 USBTerminals.PushBack(control); 493 fStreams[i]->GetFormatsAndRates(&Description); 494 // } 495 } 496 497 Vector<multi_channel_info> Channels; 498 fAudioControl.GetChannelsDescription(Channels, &Description, USBTerminals); 499 fAudioControl.GetBusChannelsDescription(Channels, &Description ); 500 501 // Description.request_channel_count = channels + bus_channels; 502 503 TraceMultiDescription(&Description, Channels); 504 505 if (user_memcpy(multiDescription, &Description, 506 sizeof(multi_description)) != B_OK) 507 return B_BAD_ADDRESS; 508 509 if (user_memcpy(multiDescription->channels, 510 &Channels[0], sizeof(multi_channel_info) * min_c(Channels.Count(), 511 Description.request_channel_count)) != B_OK) 512 return B_BAD_ADDRESS; 513 514 return B_OK; 515 } 516 517 518 void 519 Device::TraceMultiDescription(multi_description* Description, 520 Vector<multi_channel_info>& Channels) 521 { 522 TRACE(API, "interface_version:%d\n", Description->interface_version); 523 TRACE(API, "interface_minimum:%d\n", Description->interface_minimum); 524 TRACE(API, "friendly_name:%s\n", Description->friendly_name); 525 TRACE(API, "vendor_info:%s\n", Description->vendor_info); 526 TRACE(API, "output_channel_count:%d\n", Description->output_channel_count); 527 TRACE(API, "input_channel_count:%d\n", Description->input_channel_count); 528 TRACE(API, "output_bus_channel_count:%d\n", 529 Description->output_bus_channel_count); 530 TRACE(API, "input_bus_channel_count:%d\n", 531 Description->input_bus_channel_count); 532 TRACE(API, "aux_bus_channel_count:%d\n", Description->aux_bus_channel_count); 533 TRACE(API, "output_rates:%#08x\n", Description->output_rates); 534 TRACE(API, "input_rates:%#08x\n", Description->input_rates); 535 TRACE(API, "min_cvsr_rate:%f\n", Description->min_cvsr_rate); 536 TRACE(API, "max_cvsr_rate:%f\n", Description->max_cvsr_rate); 537 TRACE(API, "output_formats:%#08x\n", Description->output_formats); 538 TRACE(API, "input_formats:%#08x\n", Description->input_formats); 539 TRACE(API, "lock_sources:%d\n", Description->lock_sources); 540 TRACE(API, "timecode_sources:%d\n", Description->timecode_sources); 541 TRACE(API, "interface_flags:%#08x\n", Description->interface_flags); 542 TRACE(API, "start_latency:%d\n", Description->start_latency); 543 TRACE(API, "control_panel:%s\n", Description->control_panel); 544 545 // multi_channel_info* Channels = Description->channels; 546 // for (int i = 0; i < Description->request_channel_count; i++) { 547 for (int i = 0; i < Channels.Count(); i++) { 548 TRACE(API, " channel_id:%d\n", Channels[i].channel_id); 549 TRACE(API, " kind:%#02x\n", Channels[i].kind); 550 TRACE(API, " designations:%#08x\n", Channels[i].designations); 551 TRACE(API, " connectors:%#08x\n", Channels[i].connectors); 552 } 553 554 TRACE(API, "request_channel_count:%d\n\n", 555 Description->request_channel_count); 556 } 557 558 559 status_t 560 Device::_MultiGetEnabledChannels(multi_channel_enable* Enable) 561 { 562 status_t status = B_OK; 563 564 Enable->lock_source = B_MULTI_LOCK_INTERNAL; 565 566 uint32 offset = 0; 567 for (int i = 0; i < fStreams.Count() && status == B_OK; i++) 568 status = fStreams[i]->GetEnabledChannels(offset, Enable); 569 570 return status; 571 } 572 573 574 status_t 575 Device::_MultiSetEnabledChannels(multi_channel_enable* Enable) 576 { 577 status_t status = B_OK; 578 uint32 offset = 0; 579 for (int i = 0; i < fStreams.Count() && status == B_OK; i++) 580 status = fStreams[i]->SetEnabledChannels(offset, Enable); 581 582 return status; 583 } 584 585 586 status_t 587 Device::_MultiGetGlobalFormat(multi_format_info* Format) 588 { 589 status_t status = B_OK; 590 591 Format->output_latency = 0; 592 Format->input_latency = 0; 593 Format->timecode_kind = 0; 594 595 // uint32 offset = 0; 596 for (int i = 0; i < fStreams.Count() && status == B_OK; i++) 597 status = fStreams[i]->GetGlobalFormat(Format); 598 599 return status; 600 } 601 602 603 status_t 604 Device::_MultiSetGlobalFormat(multi_format_info* Format) 605 { 606 status_t status = B_OK; 607 608 TRACE(API, "output_latency:%lld\n", Format->output_latency); 609 TRACE(API, "input_latency:%lld\n", Format->input_latency); 610 TRACE(API, "timecode_kind:%#08x\n", Format->timecode_kind); 611 612 // uint32 offset = 0; 613 for (int i = 0; i < fStreams.Count() && status == B_OK; i++) 614 status = fStreams[i]->SetGlobalFormat(Format); 615 616 return status; 617 } 618 619 620 status_t 621 Device::_MultiGetBuffers(multi_buffer_list* List) 622 { 623 status_t status = B_OK; 624 625 TRACE(API, "info_size:%d\n" 626 "request_playback_buffers:%d\n" 627 "request_playback_channels:%d\n" 628 "request_playback_buffer_size:%d\n" 629 "request_record_buffers:%d\n" 630 "request_record_channels:%d\n" 631 "request_record_buffer_size:%d\n", 632 List->info_size, 633 List->request_playback_buffers, 634 List->request_playback_channels, 635 List->request_playback_buffer_size, 636 List->request_record_buffers, 637 List->request_record_channels, 638 List->request_record_buffer_size); 639 640 List->flags = 0; 641 List->return_playback_channels = 0; 642 List->return_record_channels = 0; 643 644 for (int i = 0; i < fStreams.Count() && status == B_OK; i++) 645 status = fStreams[i]->GetBuffers(List); 646 647 TRACE(API, "flags:%#x\n" 648 "return_playback_buffers:%d\n" 649 "return_playback_channels:%d\n" 650 "return_playback_buffer_size:%d\n" 651 "return_record_buffers:%d\n" 652 "return_record_channels:%d\n" 653 "return_record_buffer_size:%d\n", 654 List->flags, 655 List->return_playback_buffers, 656 List->return_playback_channels, 657 List->return_playback_buffer_size, 658 List->return_record_buffers, 659 List->return_record_channels, 660 List->return_record_buffer_size); 661 662 #if 0 663 TRACE(API, "playback buffers\n"); 664 for (int32_t b = 0; b < List->return_playback_buffers; b++) 665 for (int32 c = 0; c < List->return_playback_channels; c++) 666 TRACE(API, "%d:%d %08x:%d\n", b, c, List->playback_buffers[b][c].base, 667 List->playback_buffers[b][c].stride); 668 669 TRACE(API, "record buffers:\n"); 670 for (int32_t b = 0; b < List->return_record_buffers; b++) 671 for (int32 c = 0; c < List->return_record_channels; c++) 672 TRACE(API, "%d:%d %08x:%d\n", b, c, List->record_buffers[b][c].base, 673 List->record_buffers[b][c].stride); 674 #endif 675 return B_OK; 676 } 677 678 679 status_t 680 Device::_MultiBufferExchange(multi_buffer_info* multiInfo) 681 { 682 multi_buffer_info Info; 683 if (!IS_USER_ADDRESS(multiInfo) 684 || user_memcpy(&Info, multiInfo, sizeof(multi_buffer_info)) != B_OK) { 685 return B_BAD_ADDRESS; 686 } 687 688 for (int i = 0; i < fStreams.Count(); i++) 689 if (!fStreams[i]->IsRunning()) 690 fStreams[i]->Start(); 691 692 status_t status = acquire_sem_etc(fBuffersReadySem, 1, 693 B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 50000); 694 if (status == B_TIMED_OUT) { 695 TRACE(ERR, "Timeout during buffers exchange.\n"); 696 return status; 697 } 698 699 status = B_ERROR; 700 for (int i = 0; i < fStreams.Count(); i++) 701 if (fStreams[i]->ExchangeBuffer(&Info)) { 702 status = B_OK; 703 break; 704 } 705 706 if (status != B_OK) { 707 TRACE(ERR, "Error processing buffers:%08x.\n", status); 708 return status; 709 } 710 711 if (user_memcpy(multiInfo, &Info, sizeof(multi_buffer_info)) != B_OK) 712 return B_BAD_ADDRESS; 713 714 return status; 715 } 716 717 718 status_t 719 Device::_MultiBufferForceStop() 720 { 721 for (int i = 0; i < fStreams.Count(); i++) 722 fStreams[i]->Stop(); 723 return B_OK; 724 } 725 726 727 status_t 728 Device::_MultiGetMix(multi_mix_value_info* Info) 729 { 730 return fAudioControl.GetMix(Info); 731 } 732 733 734 status_t 735 Device::_MultiSetMix(multi_mix_value_info* Info) 736 { 737 return fAudioControl.SetMix(Info); 738 } 739 740 741 status_t 742 Device::_MultiListMixControls(multi_mix_control_info* Info) 743 { 744 status_t status = fAudioControl.ListMixControls(Info); 745 TraceListMixControls(Info); 746 return status; 747 } 748 749 750 void 751 Device::TraceListMixControls(multi_mix_control_info* Info) 752 { 753 TRACE(MIX, "control_count:%d\n.", Info->control_count); 754 755 int32 i = 0; 756 while (Info->controls[i].id > 0) { 757 multi_mix_control &c = Info->controls[i]; 758 TRACE(MIX, "id:%#08x\n", c.id); 759 TRACE(MIX, "flags:%#08x\n", c.flags); 760 TRACE(MIX, "master:%#08x\n", c.master); 761 TRACE(MIX, "parent:%#08x\n", c.parent); 762 TRACE(MIX, "string:%d\n", c.string); 763 TRACE(MIX, "name:%s\n", c.name); 764 i++; 765 } 766 } 767 768 769 status_t 770 Device::_SetupEndpoints() 771 { 772 const usb_configuration_info* config 773 = gUSBModule->get_nth_configuration(fDevice, 0); 774 775 if (config == NULL) { 776 TRACE(ERR, "Error of getting USB device configuration.\n"); 777 return B_ERROR; 778 } 779 780 if (config->interface_count <= 0) { 781 TRACE(ERR, "Error:no interfaces found in USB device configuration\n"); 782 return B_ERROR; 783 } 784 785 for (size_t i = 0; i < config->interface_count; i++) { 786 usb_interface_info* Interface = config->interface[i].active; 787 if (Interface->descr->interface_class != USB_AUDIO_INTERFACE_AUDIO_CLASS) 788 continue; 789 790 switch (Interface->descr->interface_subclass) { 791 case USB_AUDIO_INTERFACE_AUDIOCONTROL_SUBCLASS: 792 fAudioControl.Init(i, Interface); 793 break; 794 case USB_AUDIO_INTERFACE_AUDIOSTREAMING_SUBCLASS: 795 { 796 Stream* stream = new(std::nothrow) Stream(this, i, 797 &config->interface[i]); 798 if (B_OK == stream->Init()) { 799 // put the stream in the correct order: 800 // first output that input ones. 801 if (stream->IsInput()) 802 fStreams.PushBack(stream); 803 else 804 fStreams.PushFront(stream); 805 } else 806 delete stream; 807 } 808 break; 809 default: 810 TRACE(ERR, "Ignore interface of unsupported subclass %#x.\n", 811 Interface->descr->interface_subclass); 812 break; 813 } 814 } 815 816 if (fAudioControl.InitCheck() == B_OK && fStreams.Count() > 0) { 817 TRACE(INF, "Found device %#06x:%#06x\n", fVendorID, fProductID); 818 gUSBModule->set_configuration(fDevice, config); 819 820 for (int i = 0; i < fStreams.Count(); i++) 821 fStreams[i]->OnSetConfiguration(fDevice, config); 822 823 return B_OK; 824 } 825 826 return B_NO_INIT; 827 } 828 829 830 status_t 831 Device::StopDevice() 832 { 833 status_t result = B_OK; 834 835 if (result != B_OK) 836 TRACE(ERR, "Error of writing %#04x RX Control:%#010x\n", 0, result); 837 838 //TRACE_RET(result); 839 return result; 840 } 841 842