Changeset a333b7f in mainline for uspace/drv/audio/hdaudio/hdactl.c
- Timestamp:
- 2014-08-25T09:28:39Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 932e2f5
- Parents:
- 1412a184
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/audio/hdaudio/hdactl.c
r1412a184 ra333b7f 39 39 #include <ddi.h> 40 40 #include <errno.h> 41 #include <fibril_synch.h> 41 42 #include <macros.h> 42 43 #include <stdint.h> … … 222 223 223 224 /* Set RINTCNT - Qemu won't read from CORB if this is zero */ 224 hda_reg16_write(&hda->regs->rintcnt, 128);225 hda_reg16_write(&hda->regs->rintcnt, hda->ctl->rirb_entries / 2); 225 226 226 227 hda->ctl->rirb_rp = 0; 227 228 228 /* Start RIRB */229 /* Start RIRB and enable RIRB interrupt */ 229 230 ctl = hda_reg8_read(&hda->regs->rirbctl); 230 231 ddf_msg(LVL_NOTE, "RIRBctl (0x%x) = 0x%x", 231 232 (unsigned)((void *)&hda->regs->rirbctl - (void *)hda->regs), ctl | BIT_V(uint8_t, rirbctl_run)); 232 hda_reg8_write(&hda->regs->rirbctl, ctl | BIT_V(uint8_t, rirbctl_run)); 233 hda_reg8_write(&hda->regs->rirbctl, ctl | BIT_V(uint8_t, rirbctl_run) | 234 BIT_V(uint8_t, rirbctl_int)); 233 235 234 236 ddf_msg(LVL_NOTE, "RIRB initialized"); … … 327 329 } 328 330 329 static int hda_rirb_read(hda_t *hda, hda_rirb_entry_t *data , size_t count)331 static int hda_rirb_read(hda_t *hda, hda_rirb_entry_t *data) 330 332 { 331 333 size_t wp; 332 334 hda_rirb_entry_t resp; 333 335 hda_rirb_entry_t *rirb; 336 337 rirb = (hda_rirb_entry_t *)hda->ctl->rirb_virt; 338 339 wp = hda_get_rirbwp(hda); 340 ddf_msg(LVL_DEBUG2, "hda_rirb_read: wp=%d", wp); 341 if (hda->ctl->rirb_rp == wp) 342 return ENOENT; 343 344 ++hda->ctl->rirb_rp; 345 resp = rirb[hda->ctl->rirb_rp]; 346 347 ddf_msg(LVL_DEBUG2, "RESPONSE resp=0x%x respex=0x%x", 348 resp.resp, resp.respex); 349 *data = resp; 350 return EOK; 351 } 352 353 static int hda_solrb_read(hda_t *hda, hda_rirb_entry_t *data, size_t count) 354 { 355 hda_rirb_entry_t resp; 334 356 int wcnt; 335 357 336 rirb = (hda_rirb_entry_t *)hda->ctl->rirb_virt; 358 wcnt = 10; 359 360 fibril_mutex_lock(&hda->ctl->solrb_lock); 337 361 338 362 while (count > 0) { 339 wp = hda_get_rirbwp(hda); 340 ddf_msg(LVL_DEBUG2, "hda_rirb_read: wp=%d", wp); 341 while (count > 0 && hda->ctl->rirb_rp != wp) { 342 ++hda->ctl->rirb_rp; 343 resp = rirb[hda->ctl->rirb_rp]; 344 345 ddf_msg(LVL_DEBUG2, "RESPONSE resp=0x%x respex=0x%x", 363 while (count > 0 && hda->ctl->solrb_rp != hda->ctl->solrb_wp) { 364 ++hda->ctl->solrb_rp; 365 resp = hda->ctl->solrb[hda->ctl->solrb_rp]; 366 367 ddf_msg(LVL_DEBUG2, "solrb RESPONSE resp=0x%x respex=0x%x", 346 368 resp.resp, resp.respex); 347 369 if ((resp.respex & BIT_V(uint32_t, respex_unsol)) == 0) { … … 353 375 354 376 if (count > 0) { 355 w cnt = rirb_wait_max;356 while (wcnt > 0 && hda_get_rirbwp(hda) == hda->ctl->rirb_rp) {377 while (wcnt > 0 && hda->ctl->solrb_wp == hda->ctl->solrb_rp) { 378 fibril_mutex_unlock(&hda->ctl->solrb_lock); 357 379 async_usleep(100); 380 fibril_mutex_lock(&hda->ctl->solrb_lock); 358 381 --wcnt; 359 382 } 360 383 361 if (hda_get_rirbwp(hda) == hda->ctl->rirb_rp) 384 if (hda->ctl->solrb_wp == hda->ctl->solrb_rp) { 385 ddf_msg(LVL_NOTE, "hda_solrb_read() time out"); 386 fibril_mutex_unlock(&hda->ctl->solrb_lock); 362 387 return ETIMEOUT; 363 } 364 } 365 388 } 389 } 390 } 391 392 fibril_mutex_unlock(&hda->ctl->solrb_lock); 366 393 return EOK; 367 394 } … … 371 398 hda_ctl_t *ctl; 372 399 uint32_t gctl; 400 uint32_t intctl; 373 401 int cnt; 374 402 int rc; … … 378 406 return NULL; 379 407 408 fibril_mutex_initialize(&ctl->solrb_lock); 409 fibril_condvar_initialize(&ctl->solrb_cv); 410 380 411 hda->ctl = ctl; 412 ctl->hda = hda; 381 413 382 414 uint8_t vmaj = hda_reg8_read(&hda->regs->vmaj); … … 391 423 392 424 ddf_msg(LVL_NOTE, "reg 0x%zx STATESTS = 0x%x", 393 (void *)&hda->regs->statests - (void *)hda->regs, hda_reg16_read(&hda->regs->statests)); 425 (void *)&hda->regs->statests - (void *)hda->regs, 426 hda_reg16_read(&hda->regs->statests)); 427 /** 428 * Clear STATESTS bits so they don't generate an interrupt later 429 * when we enable interrupts. 430 */ 431 hda_reg16_write(&hda->regs->statests, 0x7f); 432 433 ddf_msg(LVL_NOTE, "after clearing reg 0x%zx STATESTS = 0x%x", 434 (void *)&hda->regs->statests - (void *)hda->regs, 435 hda_reg16_read(&hda->regs->statests)); 394 436 395 437 gctl = hda_reg32_read(&hda->regs->gctl); … … 437 479 hda_reg16_read(&hda->regs->statests)); 438 480 481 async_usleep(1000*1000); 482 483 /* Enable interrupts */ 484 intctl = hda_reg32_read(&hda->regs->intctl); 485 ddf_msg(LVL_NOTE, "intctl (0x%x) := 0x%x", 486 (unsigned)((void *)&hda->regs->intctl - (void *)hda->regs), 487 intctl | BIT_V(uint32_t, intctl_gie) | BIT_V(uint32_t, intctl_cie)); 488 hda_reg32_write(&hda->regs->intctl, intctl | 489 BIT_V(uint32_t, intctl_gie) | BIT_V(uint32_t, intctl_cie)); 490 491 async_usleep(1000*1000); 492 439 493 rc = hda_corb_init(hda); 440 494 if (rc != EOK) 441 495 goto error; 442 496 497 498 async_usleep(1000*1000); 499 443 500 rc = hda_rirb_init(hda); 444 501 if (rc != EOK) 445 502 goto error; 446 503 504 async_usleep(1000*1000); 505 506 ddf_msg(LVL_NOTE, "call hda_codec_init()"); 447 507 hda->ctl->codec = hda_codec_init(hda, 0); 448 if (hda->ctl->codec == NULL) 449 goto error; 508 if (hda->ctl->codec == NULL) { 509 ddf_msg(LVL_NOTE, "hda_codec_init() failed"); 510 goto error; 511 } 450 512 451 513 return ctl; … … 466 528 467 529 if (resp != NULL) { 468 rc = hda_ rirb_read(hda, &rentry, 1);530 rc = hda_solrb_read(hda, &rentry, 1); 469 531 if (rc != EOK) 470 532 return rc; … … 483 545 } 484 546 547 void hda_ctl_interrupt(hda_ctl_t *ctl) 548 { 549 hda_rirb_entry_t resp; 550 int rc; 551 552 while (true) { 553 rc = hda_rirb_read(ctl->hda, &resp); 554 if (rc != EOK) { 555 // ddf_msg(LVL_NOTE, "nothing in rirb"); 556 break; 557 } 558 559 ddf_msg(LVL_NOTE, "writing to solrb"); 560 fibril_mutex_lock(&ctl->solrb_lock); 561 ctl->solrb_wp = (ctl->solrb_wp + 1) % softrb_entries; 562 ctl->solrb[ctl->solrb_wp] = resp; 563 fibril_mutex_unlock(&ctl->solrb_lock); 564 fibril_condvar_broadcast(&ctl->solrb_cv); 565 } 566 } 567 485 568 /** @} 486 569 */
Note:
See TracChangeset
for help on using the changeset viewer.