1 /* 2 * Copyright 2007-2008, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Ithamar Adema, ithamar AT unet DOT nl 7 * Axel Dörfler, axeld@pinc-software.de 8 */ 9 10 11 #include "driver.h" 12 #include "hda_controller_defs.h" 13 #include "hda_codec_defs.h" 14 15 16 #define MAKE_RATE(base, multiply, divide) \ 17 ((base == 44100 ? FMT_44_1_BASE_RATE : 0) \ 18 | ((multiply - 1) << FMT_MULTIPLY_RATE_SHIFT) \ 19 | ((divide - 1) << FMT_DIVIDE_RATE_SHIFT)) 20 21 static const struct { 22 uint32 multi_rate; 23 uint32 hw_rate; 24 uint32 rate; 25 } kRates[] = { 26 {B_SR_8000, MAKE_RATE(48000, 1, 6), 8000}, 27 {B_SR_11025, MAKE_RATE(44100, 1, 4), 11025}, 28 {B_SR_16000, MAKE_RATE(48000, 1, 3), 16000}, 29 {B_SR_22050, MAKE_RATE(44100, 1, 2), 22050}, 30 {B_SR_32000, MAKE_RATE(48000, 2, 3), 32000}, 31 {B_SR_44100, MAKE_RATE(44100, 1, 1), 44100}, 32 {B_SR_48000, MAKE_RATE(48000, 1, 1), 48000}, 33 {B_SR_88200, MAKE_RATE(44100, 2, 1), 88200}, 34 {B_SR_96000, MAKE_RATE(48000, 2, 1), 96000}, 35 {B_SR_176400, MAKE_RATE(44100, 4, 1), 176400}, 36 {B_SR_192000, MAKE_RATE(48000, 4, 1), 192000}, 37 }; 38 39 40 static inline rirb_t& 41 current_rirb(hda_controller *controller) 42 { 43 return controller->rirb[controller->rirb_read_pos]; 44 } 45 46 47 static inline uint32 48 next_rirb(hda_controller *controller) 49 { 50 return (controller->rirb_read_pos + 1) % controller->rirb_length; 51 } 52 53 54 static inline uint32 55 next_corb(hda_controller *controller) 56 { 57 return (controller->corb_write_pos + 1) % controller->corb_length; 58 } 59 60 61 //! Called with interrupts off 62 static void 63 stream_handle_interrupt(hda_controller* controller, hda_stream* stream) 64 { 65 uint8 status; 66 67 if (!stream->running) 68 return; 69 70 status = OREG8(controller, stream->off, STS); 71 if (status == 0) 72 return; 73 74 OREG8(controller, stream->off, STS) = status; 75 76 if ((status & STS_BCIS) != 0) { 77 // Buffer Completed Interrupt 78 acquire_spinlock(&stream->lock); 79 80 stream->real_time = system_time(); 81 stream->frames_count += stream->buffer_length; 82 stream->buffer_cycle = (stream->buffer_cycle + 1) 83 % stream->num_buffers; 84 85 release_spinlock(&stream->lock); 86 87 release_sem_etc(stream->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE); 88 } else 89 dprintf("HDA: stream status %x\n", status); 90 } 91 92 93 static int32 94 hda_interrupt_handler(hda_controller* controller) 95 { 96 int32 rc = B_HANDLED_INTERRUPT; 97 98 /* Check if this interrupt is ours */ 99 uint32 intsts = REG32(controller, INTSTS); 100 if ((intsts & INTSTS_GIS) == 0) 101 return B_UNHANDLED_INTERRUPT; 102 103 /* Controller or stream related? */ 104 if (intsts & INTSTS_CIS) { 105 uint32 stateStatus = REG16(controller, STATESTS); 106 uint8 rirbStatus = REG8(controller, RIRBSTS); 107 uint8 corbStatus = REG8(controller, CORBSTS); 108 109 if (stateStatus) { 110 /* Detected Codec state change */ 111 REG16(controller, STATESTS) = stateStatus; 112 controller->codec_status = stateStatus; 113 } 114 115 /* Check for incoming responses */ 116 if (rirbStatus) { 117 REG8(controller, RIRBSTS) = rirbStatus; 118 119 if (rirbStatus & RIRBSTS_RINTFL) { 120 uint16 writePos = (REG16(controller, RIRBWP) + 1) 121 % controller->rirb_length; 122 123 for (; controller->rirb_read_pos != writePos; 124 controller->rirb_read_pos = next_rirb(controller)) { 125 uint32 response = current_rirb(controller).response; 126 uint32 responseFlags = current_rirb(controller).flags; 127 uint32 cad = responseFlags & RESPONSE_FLAGS_CODEC_MASK; 128 hda_codec* codec = controller->codecs[cad]; 129 130 if ((responseFlags & RESPONSE_FLAGS_UNSOLICITED) != 0) { 131 dprintf("hda: Unsolicited response: %08lx/%08lx\n", 132 response, responseFlags); 133 continue; 134 } 135 if (codec == NULL) { 136 dprintf("hda: Response for unknown codec %ld: " 137 "%08lx/%08lx\n", cad, response, responseFlags); 138 continue; 139 } 140 if (codec->response_count >= MAX_CODEC_RESPONSES) { 141 dprintf("hda: too many responses received for codec %ld" 142 ": %08lx/%08lx!\n", cad, response, responseFlags); 143 continue; 144 } 145 146 /* Store response in codec */ 147 codec->responses[codec->response_count++] = response; 148 release_sem_etc(codec->response_sem, 1, B_DO_NOT_RESCHEDULE); 149 rc = B_INVOKE_SCHEDULER; 150 } 151 } 152 153 if (rirbStatus & RIRBSTS_OIS) 154 dprintf("hda: RIRB Overflow\n"); 155 } 156 157 /* Check for sending errors */ 158 if (corbStatus) { 159 REG8(controller, CORBSTS) = corbStatus; 160 161 if (corbStatus & CORBSTS_MEI) 162 dprintf("hda: CORB Memory Error!\n"); 163 } 164 } 165 166 if (intsts & ~(INTSTS_CIS | INTSTS_GIS)) { 167 for (uint32 index = 0; index < HDA_MAX_STREAMS; index++) { 168 if ((intsts & (1 << index)) != 0) { 169 if (controller->streams[index]) { 170 stream_handle_interrupt(controller, 171 controller->streams[index]); 172 } else { 173 dprintf("hda: Stream interrupt for unconfigured stream " 174 "%ld!\n", index); 175 } 176 } 177 } 178 } 179 180 /* NOTE: See HDA001 => CIS/GIS cannot be cleared! */ 181 182 return rc; 183 } 184 185 186 static status_t 187 hda_hw_start(hda_controller* controller) 188 { 189 int timeout = 10; 190 191 // TODO: reset controller first? (we currently reset on uninit only) 192 193 /* Put controller out of reset mode */ 194 REG32(controller, GCTL) |= GCTL_CRST; 195 196 do { 197 snooze(100); 198 } while (--timeout && !(REG32(controller, GCTL) & GCTL_CRST)); 199 200 return timeout ? B_OK : B_TIMED_OUT; 201 } 202 203 204 /*! Allocates and initializes the Command Output Ring Buffer (CORB), and 205 Response Input Ring Buffer (RIRB) to the maximum supported size, and also 206 the DMA position buffer. 207 208 Programs the controller hardware to make use of these buffers (the DMA 209 positioning is actually enabled in hda_stream_setup_buffers()). 210 */ 211 static status_t 212 init_corb_rirb_pos(hda_controller* controller) 213 { 214 uint32 memSize, rirbOffset, posOffset; 215 uint8 corbSize, rirbSize, posSize; 216 status_t rc = B_OK; 217 physical_entry pe; 218 219 /* Determine and set size of CORB */ 220 corbSize = REG8(controller, CORBSIZE); 221 if (corbSize & CORBSIZE_CAP_256E) { 222 controller->corb_length = 256; 223 REG8(controller, CORBSIZE) = CORBSIZE_SZ_256E; 224 } else if (corbSize & CORBSIZE_CAP_16E) { 225 controller->corb_length = 16; 226 REG8(controller, CORBSIZE) = CORBSIZE_SZ_16E; 227 } else if (corbSize & CORBSIZE_CAP_2E) { 228 controller->corb_length = 2; 229 REG8(controller, CORBSIZE) = CORBSIZE_SZ_2E; 230 } 231 232 /* Determine and set size of RIRB */ 233 rirbSize = REG8(controller, RIRBSIZE); 234 if (rirbSize & RIRBSIZE_CAP_256E) { 235 controller->rirb_length = 256; 236 REG8(controller, RIRBSIZE) = RIRBSIZE_SZ_256E; 237 } else if (rirbSize & RIRBSIZE_CAP_16E) { 238 controller->rirb_length = 16; 239 REG8(controller, RIRBSIZE) = RIRBSIZE_SZ_16E; 240 } else if (rirbSize & RIRBSIZE_CAP_2E) { 241 controller->rirb_length = 2; 242 REG8(controller, RIRBSIZE) = RIRBSIZE_SZ_2E; 243 } 244 245 /* Determine rirb offset in memory and total size of corb+alignment+rirb */ 246 rirbOffset = (controller->corb_length * sizeof(corb_t) + 0x7f) & ~0x7f; 247 posOffset = (rirbOffset + controller->rirb_length * sizeof(rirb_t) + 0x7f) 248 & 0x7f; 249 posSize = 8 * (controller->num_input_streams 250 + controller->num_output_streams + controller->num_bidir_streams); 251 252 memSize = (posOffset + posSize + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); 253 254 /* Allocate memory area */ 255 controller->corb_rirb_pos_area = create_area("hda corb/rirb/pos", 256 (void**)&controller->corb, B_ANY_KERNEL_ADDRESS, memSize, 257 B_CONTIGUOUS, 0); 258 if (controller->corb_rirb_pos_area < 0) 259 return controller->corb_rirb_pos_area; 260 261 /* Rirb is after corb+aligment */ 262 controller->rirb = (rirb_t*)(((uint8*)controller->corb) + rirbOffset); 263 264 if ((rc = get_memory_map(controller->corb, memSize, &pe, 1)) != B_OK) { 265 delete_area(controller->corb_rirb_pos_area); 266 return rc; 267 } 268 269 /* Program CORB/RIRB for these locations */ 270 REG32(controller, CORBLBASE) = (uint32)pe.address; 271 REG32(controller, CORBUBASE) = 0; 272 REG32(controller, RIRBLBASE) = (uint32)pe.address + rirbOffset; 273 REG32(controller, RIRBUBASE) = 0; 274 275 /* Program DMA position update */ 276 REG32(controller, DMA_POSITION_BASE_LOWER) = (uint32)pe.address + posOffset; 277 REG32(controller, DMA_POSITION_BASE_UPPER) = 0; 278 279 controller->stream_positions = (uint32*) 280 ((uint8*)controller->corb + posOffset); 281 282 /* Reset CORB read pointer */ 283 /* NOTE: See HDA011 for corrected procedure! */ 284 REG16(controller, CORBRP) = CORBRP_RST; 285 do { 286 spin(10); 287 } while ( !(REG16(controller, CORBRP) & CORBRP_RST) ); 288 REG16(controller, CORBRP) = 0; 289 290 /* Reset RIRB write pointer */ 291 REG16(controller, RIRBWP) = RIRBWP_RST; 292 293 /* Generate interrupt for every response */ 294 REG16(controller, RINTCNT) = 1; 295 296 /* Setup cached read/write indices */ 297 controller->rirb_read_pos = 1; 298 controller->corb_write_pos = 0; 299 300 /* Gentlemen, start your engines... */ 301 REG8(controller, CORBCTL) = CORBCTL_RUN | CORBCTL_MEIE; 302 REG8(controller, RIRBCTL) = RIRBCTL_DMAEN | RIRBCTL_OIC | RIRBCTL_RINTCTL; 303 304 return B_OK; 305 } 306 307 308 // #pragma mark - public stream functions 309 310 311 void 312 hda_stream_delete(hda_stream* stream) 313 { 314 if (stream->buffer_ready_sem >= B_OK) 315 delete_sem(stream->buffer_ready_sem); 316 317 if (stream->buffer_area >= B_OK) 318 delete_area(stream->buffer_area); 319 320 if (stream->buffer_descriptors_area >= B_OK) 321 delete_area(stream->buffer_descriptors_area); 322 323 free(stream); 324 } 325 326 327 hda_stream* 328 hda_stream_new(hda_audio_group* audioGroup, int type) 329 { 330 hda_controller* controller = audioGroup->codec->controller; 331 332 hda_stream* stream = (hda_stream*)calloc(1, sizeof(hda_stream)); 333 if (stream == NULL) 334 return NULL; 335 336 stream->buffer_ready_sem = B_ERROR; 337 stream->buffer_area = B_ERROR; 338 stream->buffer_descriptors_area = B_ERROR; 339 stream->type = type; 340 341 switch (type) { 342 case STREAM_PLAYBACK: 343 stream->id = 1; 344 stream->off = controller->num_input_streams * HDAC_SDSIZE; 345 controller->streams[controller->num_input_streams] = stream; 346 break; 347 348 case STREAM_RECORD: 349 stream->id = 2; 350 stream->off = 0; 351 controller->streams[0] = stream; 352 break; 353 354 default: 355 dprintf("%s: Unknown stream type %d!\n", __func__, type); 356 free(stream); 357 stream = NULL; 358 break; 359 } 360 361 // find I/O and Pin widgets for this stream 362 363 if (hda_audio_group_get_widgets(audioGroup, stream) == B_OK) 364 return stream; 365 366 free(stream); 367 return NULL; 368 } 369 370 371 /*! Starts a stream's DMA engine, and enables generating and receiving 372 interrupts for this stream. 373 */ 374 status_t 375 hda_stream_start(hda_controller* controller, hda_stream* stream) 376 { 377 stream->buffer_ready_sem = create_sem(0, 378 stream->type == STREAM_PLAYBACK ? "hda_playback_sem" : "hda_record_sem"); 379 if (stream->buffer_ready_sem < B_OK) 380 return stream->buffer_ready_sem; 381 382 REG32(controller, INTCTL) |= 1 << (stream->off / HDAC_SDSIZE); 383 OREG8(controller, stream->off, CTL0) |= CTL0_IOCE | CTL0_FEIE | CTL0_DEIE 384 | CTL0_RUN; 385 386 #if 0 387 while (!(OREG8(controller, stream->off, CTL0) & CTL0_RUN)) 388 snooze(1); 389 #endif 390 391 stream->running = true; 392 393 return B_OK; 394 } 395 396 397 /*! Stops the stream's DMA engine, and turns off interrupts for this 398 stream. 399 */ 400 status_t 401 hda_stream_stop(hda_controller* controller, hda_stream* stream) 402 { 403 OREG8(controller, stream->off, CTL0) &= ~(CTL0_IOCE | CTL0_FEIE | CTL0_DEIE 404 | CTL0_RUN); 405 REG32(controller, INTCTL) &= ~(1 << (stream->off / HDAC_SDSIZE)); 406 407 #if 0 408 while ((OREG8(controller, stream->off, CTL0) & CTL0_RUN) != 0) 409 snooze(1); 410 #endif 411 412 stream->running = false; 413 delete_sem(stream->buffer_ready_sem); 414 stream->buffer_ready_sem = -1; 415 416 return B_OK; 417 } 418 419 420 status_t 421 hda_stream_setup_buffers(hda_audio_group* audioGroup, hda_stream* stream, 422 const char* desc) 423 { 424 uint32 bufferSize, bufferPhysicalAddress, alloc; 425 uint32 response[2], index; 426 physical_entry pe; 427 bdl_entry_t* bufferDescriptors; 428 corb_t verb[2]; 429 uint8* buffer; 430 status_t rc; 431 uint16 format; 432 433 /* Clear previously allocated memory */ 434 if (stream->buffer_area >= B_OK) { 435 delete_area(stream->buffer_area); 436 stream->buffer_area = B_ERROR; 437 } 438 439 if (stream->buffer_descriptors_area >= B_OK) { 440 delete_area(stream->buffer_descriptors_area); 441 stream->buffer_descriptors_area = B_ERROR; 442 } 443 444 /* Calculate size of buffer (aligned to 128 bytes) */ 445 bufferSize = stream->sample_size * stream->num_channels 446 * stream->buffer_length; 447 bufferSize = (bufferSize + 127) & (~127); 448 dprintf("HDA: sample size %ld, num channels %ld, buffer length %ld ****************\n", 449 stream->sample_size, stream->num_channels, stream->buffer_length); 450 451 /* Calculate total size of all buffers (aligned to size of B_PAGE_SIZE) */ 452 alloc = bufferSize * stream->num_buffers; 453 alloc = (alloc + B_PAGE_SIZE - 1) & (~(B_PAGE_SIZE -1)); 454 455 /* Allocate memory for buffers */ 456 stream->buffer_area = create_area("hda buffers", (void**)&buffer, 457 B_ANY_KERNEL_ADDRESS, alloc, B_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA); 458 if (stream->buffer_area < B_OK) 459 return stream->buffer_area; 460 461 /* Get the physical address of memory */ 462 rc = get_memory_map(buffer, alloc, &pe, 1); 463 if (rc != B_OK) { 464 delete_area(stream->buffer_area); 465 return rc; 466 } 467 468 bufferPhysicalAddress = (uint32)pe.address; 469 470 dprintf("%s(%s): Allocated %lu bytes for %ld buffers\n", __func__, desc, 471 alloc, stream->num_buffers); 472 473 /* Store pointers (both virtual/physical) */ 474 for (index = 0; index < stream->num_buffers; index++) { 475 stream->buffers[index] = buffer + (index * bufferSize); 476 stream->physical_buffers[index] = bufferPhysicalAddress 477 + (index * bufferSize); 478 } 479 480 /* Now allocate BDL for buffer range */ 481 alloc = stream->num_buffers * sizeof(bdl_entry_t); 482 alloc = (alloc + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); 483 484 stream->buffer_descriptors_area = create_area("hda buffer descriptors", 485 (void**)&bufferDescriptors, B_ANY_KERNEL_ADDRESS, alloc, 486 B_CONTIGUOUS, 0); 487 if (stream->buffer_descriptors_area < B_OK) { 488 delete_area(stream->buffer_area); 489 return stream->buffer_descriptors_area; 490 } 491 492 /* Get the physical address of memory */ 493 rc = get_memory_map(bufferDescriptors, alloc, &pe, 1); 494 if (rc != B_OK) { 495 delete_area(stream->buffer_area); 496 delete_area(stream->buffer_descriptors_area); 497 return rc; 498 } 499 500 stream->physical_buffer_descriptors = (uint32)pe.address; 501 502 dprintf("%s(%s): Allocated %ld bytes for %ld BDLEs\n", __func__, desc, 503 alloc, stream->num_buffers); 504 505 /* Setup buffer descriptor list (BDL) entries */ 506 for (index = 0; index < stream->num_buffers; index++, bufferDescriptors++) { 507 bufferDescriptors->address = stream->physical_buffers[index]; 508 bufferDescriptors->length = bufferSize; 509 bufferDescriptors->ioc = 1; 510 // we want an interrupt after every buffer 511 } 512 513 /* Configure stream registers */ 514 format = stream->num_channels - 1; 515 switch (stream->sample_format) { 516 case B_FMT_8BIT_S: format |= FMT_8BIT; stream->bps = 8; break; 517 case B_FMT_16BIT: format |= FMT_16BIT; stream->bps = 16; break; 518 case B_FMT_20BIT: format |= FMT_20BIT; stream->bps = 20; break; 519 case B_FMT_24BIT: format |= FMT_24BIT; stream->bps = 24; break; 520 case B_FMT_32BIT: format |= FMT_32BIT; stream->bps = 32; break; 521 522 default: 523 dprintf("%s: Invalid sample format: 0x%lx\n", __func__, 524 stream->sample_format); 525 break; 526 } 527 528 for (index = 0; index < sizeof(kRates) / sizeof(kRates[0]); index++) { 529 if (kRates[index].multi_rate == stream->sample_rate) { 530 format |= kRates[index].hw_rate; 531 stream->rate = kRates[index].rate; 532 break; 533 } 534 } 535 536 dprintf("IRA: %s: setup stream %ld: SR=%ld, SF=%ld\n", __func__, stream->id, 537 stream->rate, stream->bps); 538 539 OREG16(audioGroup->codec->controller, stream->off, FMT) = format; 540 OREG32(audioGroup->codec->controller, stream->off, BDPL) 541 = stream->physical_buffer_descriptors; 542 OREG32(audioGroup->codec->controller, stream->off, BDPU) = 0; 543 OREG16(audioGroup->codec->controller, stream->off, LVI) 544 = stream->num_buffers - 1; 545 /* total cyclic buffer size in _bytes_ */ 546 OREG32(audioGroup->codec->controller, stream->off, CBL) 547 = stream->sample_size * stream->num_channels * stream->num_buffers 548 * stream->buffer_length; 549 OREG8(audioGroup->codec->controller, stream->off, CTL2) = stream->id << 4; 550 551 REG32(audioGroup->codec->controller, DMA_POSITION_BASE_LOWER) 552 |= DMA_POSITION_ENABLED; 553 554 for (uint32 i = 0; i < stream->num_io_widgets; i++) { 555 verb[0] = MAKE_VERB(audioGroup->codec->addr, stream->io_widgets[i], 556 VID_SET_CONVERTER_FORMAT, format); 557 verb[1] = MAKE_VERB(audioGroup->codec->addr, stream->io_widgets[i], 558 VID_SET_CONVERTER_STREAM_CHANNEL, stream->id << 4); 559 hda_send_verbs(audioGroup->codec, verb, response, 2); 560 } 561 562 snooze(1000); 563 return B_OK; 564 } 565 566 567 // #pragma mark - public controller functions 568 569 570 status_t 571 hda_send_verbs(hda_codec* codec, corb_t* verbs, uint32* responses, uint32 count) 572 { 573 hda_controller *controller = codec->controller; 574 uint32 sent = 0; 575 status_t rc; 576 577 codec->response_count = 0; 578 579 while (sent < count) { 580 uint32 readPos = REG16(controller, CORBRP); 581 uint32 queued = 0; 582 583 while (sent < count) { 584 uint32 writePos = next_corb(controller); 585 586 if (writePos == readPos) { 587 // There is no space left in the ring buffer; execute the 588 // queued commands and wait until 589 break; 590 } 591 592 controller->corb[writePos] = verbs[sent++]; 593 controller->corb_write_pos = writePos; 594 queued++; 595 } 596 597 REG16(controller, CORBWP) = controller->corb_write_pos; 598 rc = acquire_sem_etc(codec->response_sem, queued, B_RELATIVE_TIMEOUT, 599 1000ULL * 50); 600 if (rc < B_OK) 601 return rc; 602 } 603 604 if (responses != NULL) 605 memcpy(responses, codec->responses, count * sizeof(uint32)); 606 607 return B_OK; 608 } 609 610 611 /*! Setup hardware for use; detect codecs; etc */ 612 status_t 613 hda_hw_init(hda_controller* controller) 614 { 615 status_t rc; 616 uint16 gcap; 617 uint32 index; 618 619 /* Map MMIO registers */ 620 controller->regs_area = map_physical_memory("hda_hw_regs", 621 (void*)controller->pci_info.u.h0.base_registers[0], 622 controller->pci_info.u.h0.base_register_sizes[0], B_ANY_KERNEL_ADDRESS, 623 0, (void**)&controller->regs); 624 if (controller->regs_area < B_OK) { 625 rc = controller->regs_area; 626 goto error; 627 } 628 629 /* Absolute minimum hw is online; we can now install interrupt handler */ 630 controller->irq = controller->pci_info.u.h0.interrupt_line; 631 rc = install_io_interrupt_handler(controller->irq, 632 (interrupt_handler)hda_interrupt_handler, controller, 0); 633 if (rc != B_OK) 634 goto no_irq; 635 636 /* show some hw features */ 637 gcap = REG16(controller, GCAP); 638 dprintf("HDA: HDA v%d.%d, O:%d/I:%d/B:%d, #SDO:%d, 64bit:%s\n", 639 REG8(controller, VMAJ), REG8(controller, VMIN), 640 GCAP_OSS(gcap), GCAP_ISS(gcap), GCAP_BSS(gcap), 641 GCAP_NSDO(gcap) ? GCAP_NSDO(gcap) *2 : 1, 642 gcap & GCAP_64OK ? "yes" : "no" ); 643 644 controller->num_input_streams = GCAP_OSS(gcap); 645 controller->num_output_streams = GCAP_ISS(gcap); 646 controller->num_bidir_streams = GCAP_BSS(gcap); 647 648 /* Get controller into valid state */ 649 rc = hda_hw_start(controller); 650 if (rc != B_OK) 651 goto reset_failed; 652 653 /* Setup CORB/RIRB/DMA POS */ 654 rc = init_corb_rirb_pos(controller); 655 if (rc != B_OK) 656 goto corb_rirb_failed; 657 658 REG16(controller, WAKEEN) = 0x7fff; 659 660 /* Enable controller interrupts */ 661 REG32(controller, INTCTL) = INTCTL_GIE | INTCTL_CIE; 662 663 /* Wait for codecs to warm up */ 664 snooze(1000); 665 666 if (!controller->codec_status) { 667 rc = ENODEV; 668 goto corb_rirb_failed; 669 } 670 671 for (index = 0; index < HDA_MAX_CODECS; index++) { 672 if ((controller->codec_status & (1 << index)) != 0) 673 hda_codec_new(controller, index); 674 } 675 676 for (index = 0; index < HDA_MAX_CODECS; index++) { 677 if (controller->codecs[index] 678 && controller->codecs[index]->num_audio_groups > 0) { 679 controller->active_codec = controller->codecs[index]; 680 break; 681 } 682 } 683 684 if (controller->active_codec != NULL) 685 return B_OK; 686 687 rc = ENODEV; 688 689 corb_rirb_failed: 690 REG32(controller, INTCTL) = 0; 691 692 reset_failed: 693 remove_io_interrupt_handler(controller->irq, 694 (interrupt_handler)hda_interrupt_handler, controller); 695 696 no_irq: 697 delete_area(controller->regs_area); 698 controller->regs_area = B_ERROR; 699 controller->regs = NULL; 700 701 error: 702 dprintf("ERROR: %s(%ld)\n", strerror(rc), rc); 703 704 return rc; 705 } 706 707 708 /*! Stop any activity */ 709 void 710 hda_hw_stop(hda_controller* controller) 711 { 712 int index; 713 714 /* Stop all audio streams */ 715 for (index = 0; index < HDA_MAX_STREAMS; index++) { 716 if (controller->streams[index] && controller->streams[index]->running) 717 hda_stream_stop(controller, controller->streams[index]); 718 } 719 } 720 721 722 /*! Free resources */ 723 void 724 hda_hw_uninit(hda_controller* controller) 725 { 726 uint32 index; 727 728 if (controller == NULL) 729 return; 730 731 /* Stop all audio streams */ 732 hda_hw_stop(controller); 733 734 /* Stop CORB/RIRB */ 735 REG8(controller, CORBCTL) = 0; 736 REG8(controller, RIRBCTL) = 0; 737 738 REG32(controller, CORBLBASE) = 0; 739 REG32(controller, RIRBLBASE) = 0; 740 REG32(controller, DMA_POSITION_BASE_LOWER) = 0; 741 742 /* Disable interrupts, reset controller, and remove interrupt handler */ 743 REG32(controller, INTCTL) = 0; 744 REG32(controller, GCTL) &= ~GCTL_CRST; 745 remove_io_interrupt_handler(controller->irq, 746 (interrupt_handler)hda_interrupt_handler, controller); 747 748 /* Delete corb/rirb area */ 749 if (controller->corb_rirb_pos_area >= 0) { 750 delete_area(controller->corb_rirb_pos_area); 751 controller->corb_rirb_pos_area = B_ERROR; 752 controller->corb = NULL; 753 controller->rirb = NULL; 754 controller->stream_positions = NULL; 755 } 756 757 /* Unmap registers */ 758 if (controller->regs_area >= 0) { 759 delete_area(controller->regs_area); 760 controller->regs_area = B_ERROR; 761 controller->regs = NULL; 762 } 763 764 /* Now delete all codecs */ 765 for (index = 0; index < HDA_MAX_CODECS; index++) { 766 if (controller->codecs[index] != NULL) 767 hda_codec_delete(controller->codecs[index]); 768 } 769 } 770 771