1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/audio/audio_driver.h> 27 #include <sys/note.h> 28 #include <sys/pci.h> 29 #include "audiohd.h" 30 31 #define DEFINTS 175 32 #define DRVNAME "audiohd" 33 /* 34 * Module linkage routines for the kernel 35 */ 36 37 static int audiohd_attach(dev_info_t *, ddi_attach_cmd_t); 38 static int audiohd_detach(dev_info_t *, ddi_detach_cmd_t); 39 static int audiohd_quiesce(dev_info_t *); 40 static int audiohd_resume(audiohd_state_t *); 41 static int audiohd_suspend(audiohd_state_t *); 42 43 /* interrupt handler */ 44 static uint_t audiohd_intr(caddr_t); 45 46 /* 47 * Local routines 48 */ 49 static int audiohd_init_state(audiohd_state_t *, dev_info_t *); 50 static int audiohd_init_pci(audiohd_state_t *, ddi_device_acc_attr_t *); 51 static void audiohd_fini_pci(audiohd_state_t *); 52 static int audiohd_reset_controller(audiohd_state_t *); 53 static int audiohd_init_controller(audiohd_state_t *); 54 static void audiohd_fini_controller(audiohd_state_t *); 55 static void audiohd_stop_dma(audiohd_state_t *); 56 static void audiohd_disable_intr(audiohd_state_t *); 57 static int audiohd_create_codec(audiohd_state_t *); 58 static void audiohd_build_path(audiohd_state_t *); 59 static void audiohd_destroy_codec(audiohd_state_t *); 60 static int audiohd_alloc_dma_mem(audiohd_state_t *, audiohd_dma_t *, 61 size_t, ddi_dma_attr_t *, uint_t); 62 static void audiohd_finish_output_path(hda_codec_t *codec); 63 static uint32_t audioha_codec_verb_get(void *, uint8_t, 64 uint8_t, uint16_t, uint8_t); 65 static uint32_t audioha_codec_4bit_verb_get(void *, uint8_t, 66 uint8_t, uint16_t, uint16_t); 67 static int audiohd_reinit_hda(audiohd_state_t *); 68 static int audiohd_response_from_codec(audiohd_state_t *statep, 69 uint32_t *resp, uint32_t *respex); 70 static void audiohd_restore_codec_gpio(audiohd_state_t *statep); 71 static void audiohd_change_speaker_state(audiohd_state_t *statep, int on); 72 static int audiohd_allocate_port(audiohd_state_t *statep); 73 static void audiohd_free_port(audiohd_state_t *statep); 74 static void audiohd_restore_path(audiohd_state_t *statep); 75 static int audiohd_add_controls(audiohd_state_t *statep); 76 static void audiohd_get_channels(audiohd_state_t *statep); 77 static void audiohd_init_path(audiohd_state_t *statep); 78 static void audiohd_del_controls(audiohd_state_t *statep); 79 80 static ddi_device_acc_attr_t hda_dev_accattr = { 81 DDI_DEVICE_ATTR_V0, 82 DDI_STRUCTURE_LE_ACC, 83 DDI_STRICTORDER_ACC 84 }; 85 86 static const char *audiohd_dtypes[] = { 87 AUDIO_PORT_LINEOUT, 88 AUDIO_PORT_SPEAKER, 89 AUDIO_PORT_HEADPHONES, 90 AUDIO_PORT_CD, 91 AUDIO_PORT_SPDIFOUT, 92 AUDIO_PORT_DIGOUT, 93 AUDIO_PORT_MODEM, 94 AUDIO_PORT_HANDSET, 95 AUDIO_PORT_LINEIN, 96 AUDIO_PORT_AUX1IN, 97 AUDIO_PORT_MIC, 98 AUDIO_PORT_PHONE, 99 AUDIO_PORT_SPDIFIN, 100 AUDIO_PORT_DIGIN, 101 AUDIO_PORT_NONE, /* reserved port, don't use */ 102 AUDIO_PORT_OTHER, 103 NULL, 104 }; 105 106 enum { 107 CTL_VOLUME = 0, 108 CTL_FRONT, 109 CTL_SPEAKER, 110 CTL_HEADPHONE, 111 CTL_REAR, 112 CTL_CENTER, 113 CTL_SURROUND, 114 CTL_LFE, 115 CTL_IGAIN, 116 CTL_LINEIN, 117 CTL_MIC, 118 CTL_CD, 119 CTL_MONGAIN, 120 CTL_MONSRC, 121 CTL_RECSRC 122 }; 123 124 static void 125 audiohd_set_chipset_info(audiohd_state_t *statep) 126 { 127 uint32_t devid; 128 const char *name; 129 const char *vers; 130 131 devid = pci_config_get16(statep->hda_pci_handle, PCI_CONF_VENID); 132 devid <<= 16; 133 devid |= pci_config_get16(statep->hda_pci_handle, PCI_CONF_DEVID); 134 135 name = AUDIOHD_DEV_CONFIG; 136 vers = AUDIOHD_DEV_VERSION; 137 138 switch (devid) { 139 case 0x80862668: 140 name = "Intel HD Audio"; 141 vers = "ICH6"; 142 break; 143 case 0x808627d8: 144 name = "Intel HD Audio"; 145 vers = "ICH7"; 146 break; 147 case 0x8086284b: 148 name = "Intel HD Audio"; 149 vers = "ICH8"; 150 break; 151 case 0x8086293e: 152 name = "Intel HD Audio"; 153 vers = "ICH9"; 154 break; 155 case 0x10de0371: 156 name = "NVIDIA HD Audio"; 157 vers = "MCP55"; 158 break; 159 case 0x10de03f0: 160 name = "NVIDIA HD Audio"; 161 vers = "MCP61A"; 162 break; 163 case 0x10de026c: 164 name = "NVIDIA HD Audio"; 165 vers = "6151"; 166 break; 167 case 0x10de03e4: 168 name = "NVIDIA HD Audio"; 169 vers = "MCP61"; 170 break; 171 case 0x10de044a: 172 name = "NVIDIA HD Audio"; 173 vers = "MCP65"; 174 break; 175 case 0x10de055c: 176 name = "NVIDIA HD Audio"; 177 vers = "MCP67"; 178 break; 179 case 0x1002437b: 180 name = "ATI HD Audio"; 181 vers = "SB450"; 182 break; 183 case 0x10024383: 184 name = "ATI HD Audio"; 185 vers = "SB600"; 186 break; 187 case 0x11063288: 188 name = "VIA HD Audio"; 189 vers = "HDA"; 190 break; 191 } 192 /* set device information */ 193 audio_dev_set_description(statep->adev, name); 194 audio_dev_set_version(statep->adev, vers); 195 } 196 197 static int 198 audiohd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 199 { 200 audiohd_state_t *statep; 201 int instance; 202 203 instance = ddi_get_instance(dip); 204 switch (cmd) { 205 case DDI_ATTACH: 206 break; 207 208 case DDI_RESUME: 209 statep = ddi_get_driver_private(dip); 210 ASSERT(statep != NULL); 211 return (audiohd_resume(statep)); 212 213 default: 214 return (DDI_FAILURE); 215 } 216 217 /* High-level interrupt isn't supported by this driver */ 218 if (ddi_intr_hilevel(dip, 0) != 0) { 219 cmn_err(CE_WARN, 220 "unsupported high level interrupt"); 221 return (DDI_FAILURE); 222 } 223 224 /* allocate the soft state structure */ 225 statep = kmem_zalloc(sizeof (*statep), KM_SLEEP); 226 ddi_set_driver_private(dip, statep); 227 228 /* interrupt cookie and initialize mutex */ 229 if (audiohd_init_state(statep, dip) != AUDIO_SUCCESS) { 230 cmn_err(CE_NOTE, 231 "audiohd_init_state failed"); 232 goto err_attach_exit3; 233 } 234 235 /* Set PCI command register to enable bus master and memeory I/O */ 236 if (audiohd_init_pci(statep, &hda_dev_accattr) != AUDIO_SUCCESS) { 237 audio_dev_warn(statep->adev, 238 "couldn't init pci regs"); 239 goto err_attach_exit4; 240 } 241 242 audiohd_set_chipset_info(statep); 243 244 if (audiohd_init_controller(statep) != AUDIO_SUCCESS) { 245 audio_dev_warn(statep->adev, 246 "couldn't init controller"); 247 goto err_attach_exit5; 248 } 249 250 if (audiohd_create_codec(statep) != AUDIO_SUCCESS) { 251 audio_dev_warn(statep->adev, 252 "couldn't create codec"); 253 goto err_attach_exit6; 254 } 255 256 audiohd_build_path(statep); 257 258 audiohd_get_channels(statep); 259 if (audiohd_allocate_port(statep) != DDI_SUCCESS) { 260 audio_dev_warn(statep->adev, "allocate port failure"); 261 goto err_attach_exit7; 262 } 263 audiohd_init_path(statep); 264 /* set up kernel statistics */ 265 if ((statep->hda_ksp = kstat_create(DRVNAME, instance, 266 DRVNAME, "controller", KSTAT_TYPE_INTR, 1, 267 KSTAT_FLAG_PERSISTENT)) != NULL) { 268 kstat_install(statep->hda_ksp); 269 } 270 271 /* disable interrupts and clear interrupt status */ 272 audiohd_disable_intr(statep); 273 274 /* set up the interrupt handler */ 275 if (ddi_add_intr(dip, 0, &statep->hda_intr_cookie, 276 (ddi_idevice_cookie_t *)NULL, audiohd_intr, (caddr_t)statep) != 277 DDI_SUCCESS) { 278 audio_dev_warn(statep->adev, 279 "bad interrupt specification "); 280 goto err_attach_exit8; 281 } 282 283 /* 284 * Register audio controls. 285 */ 286 if (audiohd_add_controls(statep) == DDI_FAILURE) { 287 audio_dev_warn(statep->adev, 288 "unable to allocate controls"); 289 goto err_attach_exit9; 290 } 291 if (audio_dev_register(statep->adev) != DDI_SUCCESS) { 292 audio_dev_warn(statep->adev, 293 "unable to register with framework"); 294 goto err_attach_exit9; 295 } 296 ddi_report_dev(dip); 297 298 /* enable interrupt */ 299 AUDIOHD_REG_SET32(AUDIOHD_REG_INTCTL, 300 AUDIOHD_INTCTL_BIT_GIE | 301 AUDIOHD_INTCTL_BIT_SIE); 302 return (DDI_SUCCESS); 303 err_attach_exit9: 304 audiohd_del_controls(statep); 305 306 err_attach_exit8: 307 if (statep->hda_ksp) 308 kstat_delete(statep->hda_ksp); 309 audiohd_free_port(statep); 310 311 err_attach_exit7: 312 audiohd_destroy_codec(statep); 313 314 err_attach_exit6: 315 audiohd_fini_controller(statep); 316 317 err_attach_exit5: 318 audiohd_fini_pci(statep); 319 320 err_attach_exit4: 321 mutex_destroy(&statep->hda_mutex); 322 323 err_attach_exit3: 324 (void) audio_dev_unregister(statep->adev); 325 326 err_attach_exit2: 327 err_attach_exit1: 328 329 return (DDI_FAILURE); 330 } 331 332 static int 333 audiohd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 334 { 335 audiohd_state_t *statep; 336 337 statep = ddi_get_driver_private(dip); 338 ASSERT(statep != NULL); 339 340 switch (cmd) { 341 case DDI_DETACH: 342 break; 343 344 case DDI_SUSPEND: 345 return (audiohd_suspend(statep)); 346 347 default: 348 return (DDI_FAILURE); 349 } 350 if (audio_dev_unregister(statep->adev) != DDI_SUCCESS) 351 return (DDI_FAILURE); 352 353 mutex_enter(&statep->hda_mutex); 354 audiohd_stop_dma(statep); 355 audiohd_disable_intr(statep); 356 mutex_exit(&statep->hda_mutex); 357 ddi_remove_intr(dip, 0, statep->hda_intr_cookie); 358 if (statep->hda_ksp) 359 kstat_delete(statep->hda_ksp); 360 audiohd_free_port(statep); 361 audiohd_destroy_codec(statep); 362 audiohd_del_controls(statep); 363 audiohd_fini_controller(statep); 364 audiohd_fini_pci(statep); 365 mutex_destroy(&statep->hda_mutex); 366 if (statep->adev) 367 audio_dev_free(statep->adev); 368 kmem_free(statep, sizeof (*statep)); 369 return (DDI_SUCCESS); 370 } 371 372 static struct dev_ops audiohd_dev_ops = { 373 DEVO_REV, /* rev */ 374 0, /* refcnt */ 375 NULL, /* getinfo */ 376 nulldev, /* identify */ 377 nulldev, /* probe */ 378 audiohd_attach, /* attach */ 379 audiohd_detach, /* detach */ 380 nodev, /* reset */ 381 NULL, /* cb_ops */ 382 NULL, /* bus_ops */ 383 NULL, /* power */ 384 audiohd_quiesce, /* quiesce */ 385 }; 386 387 static struct modldrv audiohd_modldrv = { 388 &mod_driverops, /* drv_modops */ 389 "AudioHD", /* linkinfo */ 390 &audiohd_dev_ops, /* dev_ops */ 391 }; 392 393 static struct modlinkage modlinkage = { 394 MODREV_1, 395 { &audiohd_modldrv, NULL } 396 }; 397 398 int 399 _init(void) 400 { 401 int rv; 402 403 audio_init_ops(&audiohd_dev_ops, DRVNAME); 404 if ((rv = mod_install(&modlinkage)) != 0) { 405 audio_fini_ops(&audiohd_dev_ops); 406 } 407 return (rv); 408 } 409 410 int 411 _fini(void) 412 { 413 int rv; 414 415 if ((rv = mod_remove(&modlinkage)) == 0) { 416 audio_fini_ops(&audiohd_dev_ops); 417 } 418 return (rv); 419 } 420 421 int 422 _info(struct modinfo *modinfop) 423 { 424 return (mod_info(&modlinkage, modinfop)); 425 } 426 427 /* 428 * Audio routines 429 */ 430 431 static int 432 audiohd_engine_format(void *arg) 433 { 434 _NOTE(ARGUNUSED(arg)); 435 436 return (AUDIO_FORMAT_S16_LE); 437 } 438 439 static int 440 audiohd_engine_channels(void *arg) 441 { 442 audiohd_port_t *port = arg; 443 444 return (port->nchan); 445 } 446 447 static int 448 audiohd_engine_rate(void *arg) 449 { 450 _NOTE(ARGUNUSED(arg)); 451 452 return (48000); 453 } 454 455 /* 456 * get the max channels the hardware supported 457 */ 458 static void 459 audiohd_get_channels(audiohd_state_t *statep) 460 { 461 int i; 462 uint8_t maxp, assoc; 463 464 maxp = 2; 465 for (i = 0; i < AUDIOHD_MAX_ASSOC; i++) { 466 if (maxp < statep->chann[i]) { 467 maxp = statep->chann[i]; 468 assoc = i; 469 } 470 } 471 statep->pchan = maxp; 472 statep->assoc = assoc; 473 /* for record, support stereo so far */ 474 statep->rchan = 2; 475 } 476 static void 477 audiohd_init_play_path(audiohd_path_t *path) 478 { 479 int i; 480 uint32_t ctrl; 481 uint8_t ctrl8; 482 uint8_t nchann; 483 audiohd_widget_t *widget; 484 audiohd_pin_t *pin; 485 wid_t wid; 486 audiohd_pin_color_t color; 487 488 audiohd_state_t *statep = path->statep; 489 hda_codec_t *codec = path->codec; 490 491 /* enable SPDIF output */ 492 for (i = 0; i < path->pin_nums; i++) { 493 wid = path->pin_wid[i]; 494 widget = codec->widget[wid]; 495 pin = (audiohd_pin_t *)widget->priv; 496 if (pin->device == DTYPE_SPDIF_OUT) { 497 ctrl = audioha_codec_verb_get( 498 statep, 499 codec->index, 500 path->adda_wid, 501 AUDIOHDC_VERB_GET_SPDIF_CTL, 502 0); 503 ctrl |= AUDIOHD_SPDIF_ON; 504 ctrl8 = ctrl & 505 AUDIOHD_SPDIF_MASK; 506 (void) audioha_codec_verb_get( 507 statep, 508 codec->index, 509 path->adda_wid, 510 AUDIOHDC_VERB_SET_SPDIF_LCL, 511 ctrl8); 512 /* 513 * We find that on intel ICH10 chipset with codec 514 * ALC888, audio is scratchy if we set the tag on the 515 * SPDIF path. So we just return here without setting 516 * the tag for the path as a workaround. 517 */ 518 if (codec->vid == AUDIOHD_CODECID_ALC888) { 519 return; 520 } 521 } 522 } 523 wid = path->pin_wid[0]; 524 widget = codec->widget[wid]; 525 pin = (audiohd_pin_t *)widget->priv; 526 527 /* two channels supported */ 528 if (pin->device == DTYPE_SPEAKER || 529 pin->assoc != statep->assoc) { 530 (void) audioha_codec_verb_get( 531 statep, 532 codec->index, 533 path->adda_wid, 534 AUDIOHDC_VERB_SET_STREAM_CHANN, 535 statep->port[PORT_DAC]->index << 536 AUDIOHD_PLAY_TAG_OFF); 537 (void) audioha_codec_4bit_verb_get( 538 statep, 539 codec->index, 540 path->adda_wid, 541 AUDIOHDC_VERB_SET_CONV_FMT, 542 AUDIOHD_FMT_PCM << 4 | 543 statep->pchan - 1); 544 /* multichannel supported */ 545 } else { 546 color = (pin->config >> AUDIOHD_PIN_CLR_OFF) & 547 AUDIOHD_PIN_CLR_MASK; 548 switch (color) { 549 case AUDIOHD_PIN_BLACK: 550 nchann = statep->pchan - 2; 551 break; 552 case AUDIOHD_PIN_ORANGE: 553 nchann = 2; 554 break; 555 case AUDIOHD_PIN_GREY: 556 nchann = 4; 557 break; 558 case AUDIOHD_PIN_GREEN: 559 nchann = 0; 560 break; 561 default: 562 nchann = 0; 563 break; 564 } 565 (void) audioha_codec_verb_get(statep, 566 codec->index, 567 path->adda_wid, 568 AUDIOHDC_VERB_SET_STREAM_CHANN, 569 statep->port[PORT_DAC]->index << 570 AUDIOHD_PLAY_TAG_OFF | 571 nchann); 572 (void) audioha_codec_4bit_verb_get( 573 statep, 574 codec->index, 575 path->adda_wid, 576 AUDIOHDC_VERB_SET_CONV_FMT, 577 AUDIOHD_FMT_PCM << 4 | 578 statep->pchan - 1); 579 } 580 } 581 static void 582 audiohd_init_record_path(audiohd_path_t *path) 583 { 584 audiohd_state_t *statep = path->statep; 585 hda_codec_t *codec = path->codec; 586 int i; 587 wid_t wid; 588 audiohd_pin_t *pin; 589 audiohd_widget_t *widget; 590 591 for (i = 0; i < path->pin_nums; i++) { 592 wid = path->pin_wid[i]; 593 widget = codec->widget[wid]; 594 pin = (audiohd_pin_t *)widget->priv; 595 /* 596 * Since there is no SPDIF input device available for test, 597 * we will use this code in the future to support SPDIF input 598 */ 599 #if 0 600 if (pin->device == DTYPE_SPDIF_IN) { 601 ctrl = audioha_codec_verb_get( 602 statep, 603 codec->index, 604 path->adda_wid, 605 AUDIOHDC_VERB_GET_SPDIF_CTL, 606 0); 607 ctrl |= AUDIOHD_SPDIF_ON; 608 ctrl8 = ctrl & 609 AUDIOHD_SPDIF_MASK; 610 (void) audioha_codec_verb_get( 611 statep, 612 codec->index, 613 path->adda_wid, 614 AUDIOHDC_VERB_SET_SPDIF_LCL, 615 ctrl8); 616 statep->inmask |= (1U << DTYPE_SPDIF_IN); 617 } 618 #endif 619 if (pin->device == DTYPE_MIC_IN) { 620 if (((pin->config >> 621 AUDIOHD_PIN_CONTP_OFF) & 622 AUDIOHD_PIN_CONTP_MASK) == 623 AUDIOHD_PIN_CON_FIXED) 624 statep->port[PORT_ADC]->index = path->tag; 625 } 626 if ((pin->device == DTYPE_LINE_IN) || 627 (pin->device == DTYPE_CD) || 628 (pin->device == DTYPE_MIC_IN)) { 629 statep->inmask |= (1U << pin->device); 630 } 631 } 632 (void) audioha_codec_verb_get(statep, 633 codec->index, 634 path->adda_wid, 635 AUDIOHDC_VERB_SET_STREAM_CHANN, 636 path->tag << 637 AUDIOHD_REC_TAG_OFF); 638 (void) audioha_codec_4bit_verb_get(statep, 639 codec->index, 640 path->adda_wid, 641 AUDIOHDC_VERB_SET_CONV_FMT, 642 AUDIOHD_FMT_PCM << 4 | statep->rchan - 1); 643 644 } 645 static void 646 audiohd_init_path(audiohd_state_t *statep) 647 { 648 int i; 649 audiohd_path_t *path; 650 651 for (i = 0; i < statep->pathnum; i++) { 652 path = statep->path[i]; 653 if (!path) 654 continue; 655 switch (path->path_type) { 656 case PLAY: 657 audiohd_init_play_path(path); 658 break; 659 case RECORD: 660 audiohd_init_record_path(path); 661 break; 662 default: 663 break; 664 } 665 } 666 statep->in_port = 0; 667 } 668 669 static int 670 audiohd_reset_port(audiohd_port_t *port) 671 { 672 uint16_t regbase; 673 audiohd_state_t *statep; 674 uint8_t bTmp; 675 int i; 676 677 regbase = port->regoff; 678 statep = port->statep; 679 680 bTmp = AUDIOHD_REG_GET8(regbase + AUDIOHD_SDREG_OFFSET_CTL); 681 /* stop stream */ 682 bTmp &= ~AUDIOHD_REG_RIRBSIZE; 683 AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_CTL, bTmp); 684 685 /* wait 40us for stream to stop as HD spec */ 686 drv_usecwait(40); 687 688 /* reset stream */ 689 bTmp |= AUDIOHDR_SD_CTL_SRST; 690 AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_CTL, bTmp); 691 692 for (i = 0; i < AUDIOHD_RETRY_TIMES; i++) { 693 /* Empirical testing time, which works well */ 694 drv_usecwait(50); 695 bTmp = AUDIOHD_REG_GET8(regbase + AUDIOHD_SDREG_OFFSET_CTL); 696 bTmp &= AUDIOHDR_SD_CTL_SRST; 697 if (bTmp) 698 break; 699 } 700 701 if (!bTmp) { 702 audio_dev_warn(statep->adev, "Failed to reset stream %d", 703 port->index); 704 return (AUDIO_FAILURE); 705 } 706 707 /* Empirical testing time, which works well */ 708 drv_usecwait(300); 709 710 /* exit reset stream */ 711 bTmp &= ~AUDIOHDR_SD_CTL_SRST; 712 AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_CTL, bTmp); 713 714 for (i = 0; i < AUDIOHD_RETRY_TIMES; i++) { 715 /* Empircal testing time */ 716 drv_usecwait(50); 717 bTmp = AUDIOHD_REG_GET8(regbase + AUDIOHD_SDREG_OFFSET_CTL); 718 bTmp &= AUDIOHDR_SD_CTL_SRST; 719 if (!bTmp) 720 break; 721 } 722 723 if (bTmp) { 724 audio_dev_warn(statep->adev, 725 "Failed to exit reset state for" 726 " stream %d, bTmp=0x%02x", port->index, bTmp); 727 return (AUDIO_FAILURE); 728 } 729 730 AUDIOHD_REG_SET32(regbase + AUDIOHD_SDREG_OFFSET_BDLPL, 731 (uint32_t)port->bdl_paddr); 732 AUDIOHD_REG_SET32(regbase + AUDIOHD_SDREG_OFFSET_BDLPU, 733 (uint32_t)(port->bdl_paddr >> 32)); 734 AUDIOHD_REG_SET16(regbase + AUDIOHD_SDREG_OFFSET_LVI, 735 AUDIOHD_BDLE_NUMS - 1); 736 AUDIOHD_REG_SET32(regbase + AUDIOHD_SDREG_OFFSET_CBL, 737 port->samp_size * AUDIOHD_BDLE_NUMS); 738 739 AUDIOHD_REG_SET16(regbase + AUDIOHD_SDREG_OFFSET_FORMAT, 740 port->format << 4 | port->nchan - 1); 741 742 /* clear status */ 743 AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_STS, 744 AUDIOHDR_SD_STS_BCIS | AUDIOHDR_SD_STS_FIFOE | 745 AUDIOHDR_SD_STS_DESE); 746 747 /* set stream tag */ 748 AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_CTL + 749 AUDIOHD_PLAY_CTL_OFF, 750 (port->index) << AUDIOHD_PLAY_TAG_OFF); 751 752 return (AUDIO_SUCCESS); 753 } 754 static int 755 audiohd_engine_open(void *arg, int flag, 756 unsigned *fragfrp, unsigned *nfragsp, caddr_t *bufp) 757 { 758 audiohd_port_t *port = arg; 759 audiohd_state_t *statep = port->statep; 760 761 _NOTE(ARGUNUSED(flag)); 762 763 mutex_enter(&statep->hda_mutex); 764 (void) audiohd_reset_port(port); 765 mutex_exit(&statep->hda_mutex); 766 767 port->started = B_FALSE; 768 port->count = 0; 769 port->curpos = 0; 770 *fragfrp = port->fragfr; 771 *nfragsp = AUDIOHD_BDLE_NUMS; 772 *bufp = port->samp_kaddr; 773 774 return (0); 775 } 776 777 static void 778 audiohd_start_port(audiohd_port_t *port) 779 { 780 audiohd_state_t *statep = port->statep; 781 782 ASSERT(mutex_owned(&statep->hda_mutex)); 783 784 /* if suspended, then do nothing else */ 785 if (statep->suspended) { 786 return; 787 } 788 789 /* Enable interrupt and start DMA */ 790 AUDIOHD_REG_SET8(port->regoff + AUDIOHD_SDREG_OFFSET_CTL, 791 AUDIOHDR_SD_CTL_INTS | AUDIOHDR_SD_CTL_SRUN); 792 } 793 794 static void 795 audiohd_stop_port(audiohd_port_t *port) 796 { 797 audiohd_state_t *statep = port->statep; 798 799 ASSERT(mutex_owned(&statep->hda_mutex)); 800 /* if suspended, then do nothing else */ 801 if (statep->suspended) { 802 return; 803 } 804 AUDIOHD_REG_SET8(port->regoff + AUDIOHD_SDREG_OFFSET_CTL, 0); 805 } 806 807 static int 808 audiohd_engine_start(void *arg) 809 { 810 audiohd_port_t *port = arg; 811 audiohd_state_t *statep = port->statep; 812 813 mutex_enter(&statep->hda_mutex); 814 if (!port->started) { 815 audiohd_start_port(port); 816 port->started = B_TRUE; 817 port->triggered = B_TRUE; 818 } 819 mutex_exit(&statep->hda_mutex); 820 return (0); 821 } 822 823 static void 824 audiohd_engine_stop(void *arg) 825 { 826 audiohd_port_t *port = arg; 827 audiohd_state_t *statep = port->statep; 828 829 mutex_enter(&statep->hda_mutex); 830 if (port->started) { 831 audiohd_stop_port(port); 832 } 833 port->started = B_FALSE; 834 mutex_exit(&statep->hda_mutex); 835 } 836 837 static void 838 audiohd_update_port(audiohd_port_t *port) 839 { 840 int pos; 841 uint32_t len; 842 audiohd_state_t *statep = port->statep; 843 844 pos = AUDIOHD_REG_GET32(port->regoff + AUDIOHD_SDREG_OFFSET_LPIB); 845 pos &= AUDIOHD_POS_MASK; 846 if (pos > port->curpos) 847 len = (pos - port->curpos) & AUDIOHD_POS_MASK; 848 else { 849 len = pos + port->samp_size * AUDIOHD_BDLE_NUMS - port->curpos; 850 len &= AUDIOHD_POS_MASK; 851 } 852 port->curpos += len; 853 if (port->curpos >= port->samp_size * AUDIOHD_BDLE_NUMS) 854 port->curpos -= port->samp_size * AUDIOHD_BDLE_NUMS; 855 856 port->len = len; 857 port->count += len / (port->nchan * 2); 858 859 860 } 861 862 static uint64_t 863 audiohd_engine_count(void *arg) 864 { 865 audiohd_port_t *port = arg; 866 audiohd_state_t *statep = port->statep; 867 uint64_t val; 868 869 mutex_enter(&statep->hda_mutex); 870 audiohd_update_port(port); 871 val = port->count; 872 mutex_exit(&statep->hda_mutex); 873 return (val); 874 } 875 876 static void 877 audiohd_engine_close(void *arg) 878 { 879 audiohd_port_t *port = arg; 880 audiohd_state_t *statep = port->statep; 881 882 mutex_enter(&statep->hda_mutex); 883 audiohd_stop_port(port); 884 port->started = B_FALSE; 885 port->triggered = B_FALSE; 886 mutex_exit(&statep->hda_mutex); 887 } 888 889 static void 890 audiohd_engine_sync(void *arg, unsigned nframes) 891 { 892 audiohd_port_t *port = arg; 893 894 _NOTE(ARGUNUSED(nframes)); 895 896 (void) ddi_dma_sync(port->samp_dmah, port->curpos, 897 port->len, port->sync_dir); 898 899 } 900 901 static size_t 902 audiohd_engine_qlen(void *arg) 903 { 904 audiohd_port_t *port = arg; 905 906 return (port->fragfr); 907 } 908 909 audio_engine_ops_t audiohd_engine_ops = { 910 AUDIO_ENGINE_VERSION, /* version number */ 911 audiohd_engine_open, 912 audiohd_engine_close, 913 audiohd_engine_start, 914 audiohd_engine_stop, 915 audiohd_engine_count, 916 audiohd_engine_format, 917 audiohd_engine_channels, 918 audiohd_engine_rate, 919 audiohd_engine_sync, 920 audiohd_engine_qlen, 921 }; 922 923 static int 924 audiohd_get_value(void *arg, uint64_t *val) 925 { 926 audiohd_ctrl_t *pc = arg; 927 audiohd_state_t *statep = pc->statep; 928 929 mutex_enter(&statep->hda_mutex); 930 *val = pc->val; 931 mutex_exit(&statep->hda_mutex); 932 return (0); 933 } 934 935 static void 936 audiohd_set_output_gain(audiohd_state_t *statep) 937 { 938 int i; 939 audiohd_path_t *path; 940 uint_t tmp; 941 wid_t wid; 942 audiohd_widget_t *w; 943 uint8_t gain; 944 uint32_t maxgain; 945 946 if (statep->soft_volume) 947 return; 948 gain = (uint8_t)statep->controls[CTL_VOLUME]->val; 949 for (i = 0; i < statep->pathnum; i++) { 950 path = statep->path[i]; 951 if (!path || path->path_type != PLAY) 952 continue; 953 /* use the DACs to adjust the volume */ 954 wid = path->adda_wid; 955 w = path->codec->widget[wid]; 956 maxgain = w->outamp_cap & 957 AUDIOHDC_AMP_CAP_STEP_NUMS; 958 maxgain >>= AUDIOHD_GAIN_OFF; 959 if (w->outamp_cap) { 960 tmp = gain * maxgain / 100; 961 (void) audioha_codec_4bit_verb_get(statep, 962 path->codec->index, 963 wid, 964 AUDIOHDC_VERB_SET_AMP_MUTE, 965 AUDIOHDC_AMP_SET_LEFT | 966 AUDIOHDC_AMP_SET_OUTPUT | tmp); 967 (void) audioha_codec_4bit_verb_get(statep, 968 path->codec->index, 969 wid, 970 AUDIOHDC_VERB_SET_AMP_MUTE, 971 AUDIOHDC_AMP_SET_RIGHT | 972 AUDIOHDC_AMP_SET_OUTPUT | tmp); 973 } 974 } 975 } 976 977 static void 978 audiohd_do_set_pin_volume(audiohd_state_t *statep, audiohd_path_t *path, 979 audiohd_pin_t *pin, uint64_t val) 980 { 981 uint8_t l, r; 982 uint_t tmp; 983 int gain; 984 985 if (val == 0) { 986 (void) audioha_codec_4bit_verb_get( 987 statep, 988 path->codec->index, 989 pin->mute_wid, 990 AUDIOHDC_VERB_SET_AMP_MUTE, 991 pin->mute_dir | 992 AUDIOHDC_AMP_SET_LNR | 993 AUDIOHDC_AMP_SET_MUTE); 994 return; 995 } 996 997 l = (val & 0xff00) >> 8; 998 r = (val & 0xff); 999 1000 tmp = l * pin->gain_bits / 100; 1001 (void) audioha_codec_4bit_verb_get(statep, 1002 path->codec->index, 1003 pin->gain_wid, 1004 AUDIOHDC_VERB_SET_AMP_MUTE, 1005 AUDIOHDC_AMP_SET_LEFT | pin->gain_dir | 1006 tmp); 1007 tmp = r * pin->gain_bits / 100; 1008 (void) audioha_codec_4bit_verb_get(statep, 1009 path->codec->index, 1010 pin->gain_wid, 1011 AUDIOHDC_VERB_SET_AMP_MUTE, 1012 AUDIOHDC_AMP_SET_RIGHT | pin->gain_dir | 1013 tmp); 1014 if (pin->mute_wid != pin->gain_wid) { 1015 gain = AUDIOHDC_GAIN_MAX; 1016 (void) audioha_codec_4bit_verb_get( 1017 statep, 1018 path->codec->index, 1019 pin->mute_wid, 1020 AUDIOHDC_VERB_SET_AMP_MUTE, 1021 pin->mute_dir | 1022 AUDIOHDC_AMP_SET_LEFT | 1023 gain); 1024 (void) audioha_codec_4bit_verb_get( 1025 statep, 1026 path->codec->index, 1027 pin->mute_wid, 1028 AUDIOHDC_VERB_SET_AMP_MUTE, 1029 pin->mute_dir | 1030 AUDIOHDC_AMP_SET_RIGHT | 1031 gain); 1032 } 1033 } 1034 1035 static void 1036 audiohd_set_pin_volume(audiohd_state_t *statep, audiohda_device_type_t type) 1037 { 1038 int i, j; 1039 audiohd_path_t *path; 1040 audiohd_widget_t *widget; 1041 wid_t wid; 1042 audiohd_pin_t *pin; 1043 hda_codec_t *codec; 1044 uint64_t val; 1045 audiohd_ctrl_t *control; 1046 1047 switch (type) { 1048 case DTYPE_SPEAKER: 1049 control = statep->controls[CTL_SPEAKER]; 1050 if (control == NULL) 1051 return; 1052 val = control->val; 1053 break; 1054 case DTYPE_HP_OUT: 1055 control = statep->controls[CTL_HEADPHONE]; 1056 if (control == NULL) 1057 return; 1058 val = control->val; 1059 break; 1060 case DTYPE_CD: 1061 control = statep->controls[CTL_CD]; 1062 if (control == NULL) 1063 return; 1064 val = control->val; 1065 break; 1066 case DTYPE_LINE_IN: 1067 control = statep->controls[CTL_LINEIN]; 1068 if (control == NULL) 1069 return; 1070 val = control->val; 1071 break; 1072 case DTYPE_MIC_IN: 1073 control = statep->controls[CTL_MIC]; 1074 if (control == NULL) 1075 return; 1076 val = control->val; 1077 break; 1078 } 1079 1080 for (i = 0; i < statep->pathnum; i++) { 1081 path = statep->path[i]; 1082 if (!path) 1083 continue; 1084 codec = path->codec; 1085 for (j = 0; j < path->pin_nums; j++) { 1086 wid = path->pin_wid[j]; 1087 widget = codec->widget[wid]; 1088 pin = (audiohd_pin_t *)widget->priv; 1089 if ((pin->device == type) && pin->gain_wid) { 1090 audiohd_do_set_pin_volume(statep, path, 1091 pin, val); 1092 } 1093 } 1094 } 1095 } 1096 1097 1098 static void 1099 audiohd_set_pin_volume_by_color(audiohd_state_t *statep, 1100 audiohd_pin_color_t color) 1101 { 1102 int i, j; 1103 audiohd_path_t *path; 1104 audiohd_widget_t *widget; 1105 wid_t wid; 1106 audiohd_pin_t *pin; 1107 hda_codec_t *codec; 1108 uint8_t l, r; 1109 uint64_t val; 1110 audiohd_pin_color_t clr; 1111 audiohd_ctrl_t *control; 1112 1113 switch (color) { 1114 case AUDIOHD_PIN_GREEN: 1115 control = statep->controls[CTL_FRONT]; 1116 if (control == NULL) 1117 return; 1118 val = control->val; 1119 break; 1120 case AUDIOHD_PIN_BLACK: 1121 control = statep->controls[CTL_REAR]; 1122 if (control == NULL) 1123 return; 1124 val = control->val; 1125 break; 1126 case AUDIOHD_PIN_ORANGE: 1127 control = statep->controls[CTL_CENTER]; 1128 if (control == NULL) 1129 return; 1130 l = control->val; 1131 control = statep->controls[CTL_LFE]; 1132 if (control == NULL) 1133 return; 1134 r = control->val; 1135 val = (l << 8) | r; 1136 break; 1137 case AUDIOHD_PIN_GREY: 1138 control = statep->controls[CTL_SURROUND]; 1139 if (control == NULL) 1140 return; 1141 val = control->val; 1142 break; 1143 } 1144 1145 for (i = 0; i < statep->pathnum; i++) { 1146 path = statep->path[i]; 1147 if (!path) 1148 continue; 1149 codec = path->codec; 1150 for (j = 0; j < path->pin_nums; j++) { 1151 wid = path->pin_wid[j]; 1152 widget = codec->widget[wid]; 1153 pin = (audiohd_pin_t *)widget->priv; 1154 clr = (pin->config >> AUDIOHD_PIN_CLR_OFF) & 1155 AUDIOHD_PIN_CLR_MASK; 1156 if ((clr == color) && pin->gain_wid) { 1157 audiohd_do_set_pin_volume(statep, path, 1158 pin, val); 1159 } 1160 } 1161 } 1162 } 1163 1164 static int 1165 audiohd_set_input_pin(audiohd_state_t *statep) 1166 { 1167 uint64_t val; 1168 audiohd_pin_t *pin; 1169 audiohd_path_t *path; 1170 audiohd_widget_t *widget; 1171 int i, j; 1172 wid_t wid; 1173 1174 val = statep->controls[CTL_RECSRC]->val; 1175 for (i = 0; i < statep->pathnum; i++) { 1176 path = statep->path[i]; 1177 if (!path || path->path_type != RECORD) 1178 continue; 1179 switch ((ddi_ffs(val & 0xffff)) - 1) { 1180 case DTYPE_LINE_IN: 1181 case DTYPE_MIC_IN: 1182 case DTYPE_CD: 1183 for (j = 0; j < path->pin_nums; j++) { 1184 wid = path->pin_wid[j]; 1185 widget = path->codec->widget[wid]; 1186 pin = (audiohd_pin_t *)widget->priv; 1187 if ((1U << pin->device) == val) { 1188 AUDIOHD_ENABLE_PIN_IN(statep, 1189 path->codec->index, 1190 pin->wid); 1191 statep->in_port = pin->device; 1192 } else if (statep->in_port == pin->device) { 1193 AUDIOHD_DISABLE_PIN_IN(statep, 1194 path->codec->index, 1195 pin->wid); 1196 } 1197 } 1198 break; 1199 default: 1200 break; 1201 } 1202 break; 1203 } 1204 return (DDI_SUCCESS); 1205 } 1206 1207 static void 1208 audiohd_set_pin_monitor_gain(hda_codec_t *codec, audiohd_state_t *statep, 1209 uint_t caddr, audiohd_pin_t *pin, uint64_t gain) 1210 { 1211 int i, k; 1212 uint_t ltmp, rtmp; 1213 audiohd_widget_t *widget; 1214 uint8_t l, r; 1215 1216 l = (gain & 0xff00) >> 8; 1217 r = (gain & 0xff); 1218 1219 for (k = 0; k < pin->num; k++) { 1220 ltmp = l * pin->mg_gain[k] / 100; 1221 rtmp = r * pin->mg_gain[k] / 100; 1222 widget = codec->widget[pin->mg_wid[k]]; 1223 if (pin->mg_dir[k] == AUDIOHDC_AMP_SET_OUTPUT) { 1224 (void) audioha_codec_4bit_verb_get( 1225 statep, 1226 caddr, 1227 pin->mg_wid[k], 1228 AUDIOHDC_VERB_SET_AMP_MUTE, 1229 AUDIOHDC_AMP_SET_LEFT| 1230 pin->mg_dir[k] | ltmp); 1231 (void) audioha_codec_4bit_verb_get( 1232 statep, 1233 caddr, 1234 pin->mg_wid[k], 1235 AUDIOHDC_VERB_SET_AMP_MUTE, 1236 AUDIOHDC_AMP_SET_RIGHT| 1237 pin->mg_dir[k] | rtmp); 1238 } else if (pin->mg_dir[k] == AUDIOHDC_AMP_SET_INPUT) { 1239 for (i = 0; i < widget->used; i++) { 1240 (void) audioha_codec_4bit_verb_get( 1241 statep, 1242 caddr, 1243 pin->mg_wid[k], 1244 AUDIOHDC_VERB_SET_AMP_MUTE, 1245 AUDIOHDC_AMP_SET_RIGHT| 1246 widget->selmon[i]<< 1247 AUDIOHDC_AMP_SET_INDEX_OFFSET | 1248 pin->mg_dir[k] | rtmp); 1249 (void) audioha_codec_4bit_verb_get( 1250 statep, 1251 caddr, 1252 pin->mg_wid[k], 1253 AUDIOHDC_VERB_SET_AMP_MUTE, 1254 AUDIOHDC_AMP_SET_LEFT| 1255 widget->selmon[i]<< 1256 AUDIOHDC_AMP_SET_INDEX_OFFSET | 1257 pin->mg_dir[k] | ltmp); 1258 } 1259 } 1260 } 1261 } 1262 1263 static void 1264 audiohd_set_monitor_gain(audiohd_state_t *statep) 1265 { 1266 int i, j; 1267 audiohd_path_t *path; 1268 uint_t caddr; 1269 audiohd_widget_t *w; 1270 wid_t wid; 1271 audiohd_pin_t *pin; 1272 audiohd_ctrl_t *ctrl; 1273 uint64_t val; 1274 1275 ctrl = statep->controls[CTL_MONGAIN]; 1276 if (ctrl == NULL) 1277 return; 1278 val = ctrl->val; 1279 1280 for (i = 0; i < statep->pathnum; i++) { 1281 path = statep->path[i]; 1282 if (path == NULL || path->path_type != PLAY) 1283 continue; 1284 caddr = path->codec->index; 1285 for (j = 0; j < path->pin_nums; j++) { 1286 wid = path->pin_wid[j]; 1287 w = path->codec->widget[wid]; 1288 pin = (audiohd_pin_t *)w->priv; 1289 audiohd_set_pin_monitor_gain(path->codec, statep, 1290 caddr, pin, val); 1291 } 1292 } 1293 1294 } 1295 1296 static void 1297 audiohd_restore_volume(audiohd_state_t *statep) 1298 { 1299 audiohd_set_pin_volume(statep, DTYPE_LINEOUT); 1300 audiohd_set_pin_volume(statep, DTYPE_SPEAKER); 1301 audiohd_set_pin_volume(statep, DTYPE_HP_OUT); 1302 1303 audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_BLACK); 1304 audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_GREY); 1305 audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_ORANGE); 1306 } 1307 static void 1308 audiohd_configure_output(audiohd_state_t *statep) 1309 { 1310 audiohd_set_output_gain(statep); 1311 } 1312 static void 1313 audiohd_configure_input(audiohd_state_t *statep) 1314 { 1315 (void) audiohd_set_input_pin(statep); 1316 audiohd_set_monitor_gain(statep); 1317 audiohd_set_pin_volume(statep, DTYPE_LINE_IN); 1318 audiohd_set_pin_volume(statep, DTYPE_CD); 1319 audiohd_set_pin_volume(statep, DTYPE_MIC_IN); 1320 } 1321 static int 1322 audiohd_set_volume(void *arg, uint64_t val) 1323 { 1324 audiohd_ctrl_t *pc = arg; 1325 audiohd_state_t *statep = pc->statep; 1326 1327 val &= 0xff; 1328 if (val > 100) 1329 return (EINVAL); 1330 1331 mutex_enter(&statep->hda_mutex); 1332 pc->val = val; 1333 audiohd_configure_output(statep); 1334 mutex_exit(&statep->hda_mutex); 1335 1336 return (0); 1337 } 1338 1339 static int 1340 audiohd_set_recsrc(void *arg, uint64_t val) 1341 { 1342 audiohd_ctrl_t *pc = arg; 1343 audiohd_state_t *statep = pc->statep; 1344 1345 if (val & ~(statep->inmask)) 1346 return (EINVAL); 1347 1348 mutex_enter(&statep->hda_mutex); 1349 pc->val = val; 1350 audiohd_configure_input(statep); 1351 mutex_exit(&statep->hda_mutex); 1352 return (0); 1353 } 1354 1355 static int 1356 audiohd_set_rear(void *arg, uint64_t val) 1357 { 1358 audiohd_ctrl_t *pc = arg; 1359 audiohd_state_t *statep = pc->statep; 1360 uint8_t l, r; 1361 1362 if (val & ~0xffff) 1363 return (EINVAL); 1364 1365 l = (val & 0xff00) >> 8; 1366 r = (val & 0xff); 1367 if ((l > 100) || (r > 100)) 1368 return (EINVAL); 1369 1370 mutex_enter(&statep->hda_mutex); 1371 pc->val = val; 1372 audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_BLACK); 1373 mutex_exit(&statep->hda_mutex); 1374 1375 return (0); 1376 } 1377 1378 static int 1379 audiohd_set_center(void *arg, uint64_t val) 1380 { 1381 audiohd_ctrl_t *pc = arg; 1382 audiohd_state_t *statep = pc->statep; 1383 1384 val &= 0xff; 1385 1386 if (val > 100) 1387 return (EINVAL); 1388 1389 mutex_enter(&statep->hda_mutex); 1390 pc->val = val; 1391 audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_ORANGE); 1392 mutex_exit(&statep->hda_mutex); 1393 1394 return (0); 1395 } 1396 1397 static int 1398 audiohd_set_surround(void *arg, uint64_t val) 1399 { 1400 audiohd_ctrl_t *pc = arg; 1401 audiohd_state_t *statep = pc->statep; 1402 uint8_t l, r; 1403 1404 if (val & ~0xffff) 1405 return (EINVAL); 1406 1407 l = (val & 0xff00) >> 8; 1408 r = (val & 0xff); 1409 if ((l > 100) || (r > 100)) 1410 return (EINVAL); 1411 1412 mutex_enter(&statep->hda_mutex); 1413 pc->val = val; 1414 audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_GREY); 1415 mutex_exit(&statep->hda_mutex); 1416 1417 return (0); 1418 } 1419 1420 static int 1421 audiohd_set_lfe(void *arg, uint64_t val) 1422 { 1423 audiohd_ctrl_t *pc = arg; 1424 audiohd_state_t *statep = pc->statep; 1425 1426 val &= 0xff; 1427 1428 if (val > 100) 1429 return (EINVAL); 1430 1431 mutex_enter(&statep->hda_mutex); 1432 pc->val = val; 1433 audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_ORANGE); 1434 mutex_exit(&statep->hda_mutex); 1435 1436 return (0); 1437 } 1438 static int 1439 audiohd_set_speaker(void *arg, uint64_t val) 1440 { 1441 audiohd_ctrl_t *pc = arg; 1442 audiohd_state_t *statep = pc->statep; 1443 uint8_t l, r; 1444 1445 if (val & ~0xffff) 1446 return (EINVAL); 1447 1448 l = (val & 0xff00) >> 8; 1449 r = (val & 0xff); 1450 if ((l > 100) || (r > 100)) 1451 return (EINVAL); 1452 1453 mutex_enter(&statep->hda_mutex); 1454 pc->val = val; 1455 audiohd_set_pin_volume(statep, DTYPE_SPEAKER); 1456 mutex_exit(&statep->hda_mutex); 1457 1458 return (0); 1459 } 1460 static int 1461 audiohd_set_front(void *arg, uint64_t val) 1462 { 1463 audiohd_ctrl_t *pc = arg; 1464 audiohd_state_t *statep = pc->statep; 1465 uint8_t l, r; 1466 1467 if (val & ~0xffff) 1468 return (EINVAL); 1469 1470 l = (val & 0xff00) >> 8; 1471 r = (val & 0xff); 1472 if ((l > 100) || (r > 100)) 1473 return (EINVAL); 1474 1475 mutex_enter(&statep->hda_mutex); 1476 pc->val = val; 1477 audiohd_set_pin_volume_by_color(statep, AUDIOHD_PIN_GREEN); 1478 mutex_exit(&statep->hda_mutex); 1479 1480 return (0); 1481 } 1482 static int 1483 audiohd_set_headphone(void *arg, uint64_t val) 1484 { 1485 audiohd_ctrl_t *pc = arg; 1486 audiohd_state_t *statep = pc->statep; 1487 uint8_t l, r; 1488 1489 if (val & ~0xffff) 1490 return (EINVAL); 1491 1492 l = (val & 0xff00) >> 8; 1493 r = (val & 0xff); 1494 if ((l > 100) || (r > 100)) 1495 return (EINVAL); 1496 1497 mutex_enter(&statep->hda_mutex); 1498 pc->val = val; 1499 audiohd_set_pin_volume(statep, DTYPE_HP_OUT); 1500 mutex_exit(&statep->hda_mutex); 1501 1502 return (0); 1503 } 1504 static int 1505 audiohd_set_linein(void *arg, uint64_t val) 1506 { 1507 audiohd_ctrl_t *pc = arg; 1508 audiohd_state_t *statep = pc->statep; 1509 uint8_t l, r; 1510 1511 if (val & ~0xffff) 1512 return (EINVAL); 1513 1514 l = (val & 0xff00) >> 8; 1515 r = (val & 0xff); 1516 if ((l > 100) || (r > 100)) 1517 return (EINVAL); 1518 1519 mutex_enter(&statep->hda_mutex); 1520 pc->val = val; 1521 audiohd_set_pin_volume(statep, DTYPE_LINE_IN); 1522 mutex_exit(&statep->hda_mutex); 1523 1524 return (0); 1525 } 1526 1527 static int 1528 audiohd_set_mic(void *arg, uint64_t val) 1529 { 1530 audiohd_ctrl_t *pc = arg; 1531 audiohd_state_t *statep = pc->statep; 1532 uint8_t l, r; 1533 1534 if (val & ~0xffff) 1535 return (EINVAL); 1536 1537 l = (val & 0xff00) >> 8; 1538 r = (val & 0xff); 1539 if ((l > 100) || (r > 100)) 1540 return (EINVAL); 1541 1542 mutex_enter(&statep->hda_mutex); 1543 pc->val = val; 1544 audiohd_set_pin_volume(statep, DTYPE_MIC_IN); 1545 mutex_exit(&statep->hda_mutex); 1546 1547 return (0); 1548 } 1549 1550 static int 1551 audiohd_set_cd(void *arg, uint64_t val) 1552 { 1553 audiohd_ctrl_t *pc = arg; 1554 audiohd_state_t *statep = pc->statep; 1555 uint8_t l, r; 1556 1557 if (val & ~0xffff) 1558 return (EINVAL); 1559 1560 l = (val & 0xff00) >> 8; 1561 r = (val & 0xff); 1562 if ((l > 100) || (r > 100)) 1563 return (EINVAL); 1564 1565 mutex_enter(&statep->hda_mutex); 1566 pc->val = val; 1567 audiohd_set_pin_volume(statep, DTYPE_CD); 1568 mutex_exit(&statep->hda_mutex); 1569 1570 return (0); 1571 } 1572 1573 static int 1574 audiohd_set_mongain(void *arg, uint64_t val) 1575 { 1576 audiohd_ctrl_t *pc = arg; 1577 audiohd_state_t *statep = pc->statep; 1578 uint8_t l, r; 1579 1580 if (val & ~0xffff) 1581 return (EINVAL); 1582 1583 l = (val & 0xff00) >> 8; 1584 r = (val & 0xff); 1585 if ((l > 100) || (r > 100)) 1586 return (EINVAL); 1587 1588 mutex_enter(&statep->hda_mutex); 1589 pc->val = val; 1590 audiohd_configure_input(statep); 1591 mutex_exit(&statep->hda_mutex); 1592 1593 return (0); 1594 } 1595 1596 #define PLAYCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY) 1597 #define RECCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC) 1598 #define MONCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR) 1599 #define PCMVOL (PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL) 1600 #define MONVOL (MONCTL | AUDIO_CTRL_FLAG_MONVOL) 1601 #define MAINVOL (PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL) 1602 #define RECVOL (RECCTL | AUDIO_CTRL_FLAG_RECVOL) 1603 1604 static audiohd_ctrl_t * 1605 audiohd_alloc_ctrl(audiohd_state_t *statep, uint32_t num, uint64_t val) 1606 { 1607 audio_ctrl_desc_t desc; 1608 audio_ctrl_wr_t fn; 1609 audiohd_ctrl_t *pc; 1610 1611 pc = kmem_zalloc(sizeof (*pc), KM_SLEEP); 1612 pc->statep = statep; 1613 pc->num = num; 1614 1615 bzero(&desc, sizeof (desc)); 1616 1617 switch (num) { 1618 case CTL_VOLUME: 1619 desc.acd_name = AUDIO_CTRL_ID_VOLUME; 1620 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 1621 desc.acd_minvalue = 0; 1622 desc.acd_maxvalue = 100; 1623 desc.acd_flags = PCMVOL; 1624 fn = audiohd_set_volume; 1625 break; 1626 1627 case CTL_FRONT: 1628 desc.acd_name = AUDIO_CTRL_ID_FRONT; 1629 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1630 desc.acd_minvalue = 0; 1631 desc.acd_maxvalue = 100; 1632 desc.acd_flags = MAINVOL; 1633 fn = audiohd_set_front; 1634 break; 1635 1636 case CTL_SPEAKER: 1637 desc.acd_name = AUDIO_CTRL_ID_SPEAKER; 1638 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1639 desc.acd_minvalue = 0; 1640 desc.acd_maxvalue = 100; 1641 desc.acd_flags = MAINVOL; 1642 fn = audiohd_set_speaker; 1643 break; 1644 1645 case CTL_HEADPHONE: 1646 desc.acd_name = AUDIO_CTRL_ID_HEADPHONE; 1647 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1648 desc.acd_minvalue = 0; 1649 desc.acd_maxvalue = 100; 1650 desc.acd_flags = MAINVOL; 1651 fn = audiohd_set_headphone; 1652 break; 1653 1654 case CTL_REAR: 1655 desc.acd_name = AUDIO_CTRL_ID_REAR; 1656 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1657 desc.acd_minvalue = 0; 1658 desc.acd_maxvalue = 100; 1659 desc.acd_flags = MAINVOL; 1660 fn = audiohd_set_rear; 1661 break; 1662 1663 case CTL_CENTER: 1664 desc.acd_name = AUDIO_CTRL_ID_CENTER; 1665 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 1666 desc.acd_minvalue = 0; 1667 desc.acd_maxvalue = 100; 1668 desc.acd_flags = MAINVOL; 1669 fn = audiohd_set_center; 1670 break; 1671 1672 case CTL_SURROUND: 1673 desc.acd_name = AUDIO_CTRL_ID_SURROUND; 1674 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1675 desc.acd_minvalue = 0; 1676 desc.acd_maxvalue = 100; 1677 desc.acd_flags = MAINVOL; 1678 fn = audiohd_set_surround; 1679 break; 1680 1681 case CTL_LFE: 1682 desc.acd_name = AUDIO_CTRL_ID_LFE; 1683 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 1684 desc.acd_minvalue = 0; 1685 desc.acd_maxvalue = 100; 1686 desc.acd_flags = MAINVOL; 1687 fn = audiohd_set_lfe; 1688 break; 1689 1690 case CTL_LINEIN: 1691 desc.acd_name = AUDIO_CTRL_ID_LINEIN; 1692 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1693 desc.acd_minvalue = 0; 1694 desc.acd_maxvalue = 100; 1695 desc.acd_flags = RECVOL; 1696 fn = audiohd_set_linein; 1697 break; 1698 1699 case CTL_MIC: 1700 desc.acd_name = AUDIO_CTRL_ID_MIC; 1701 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1702 desc.acd_minvalue = 0; 1703 desc.acd_maxvalue = 100; 1704 desc.acd_flags = RECVOL; 1705 fn = audiohd_set_mic; 1706 break; 1707 1708 case CTL_CD: 1709 desc.acd_name = AUDIO_CTRL_ID_CD; 1710 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1711 desc.acd_minvalue = 0; 1712 desc.acd_maxvalue = 100; 1713 desc.acd_flags = RECVOL; 1714 fn = audiohd_set_cd; 1715 break; 1716 1717 case CTL_MONGAIN: 1718 desc.acd_name = AUDIO_CTRL_ID_MONGAIN; 1719 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1720 desc.acd_minvalue = 0; 1721 desc.acd_maxvalue = 100; 1722 desc.acd_flags = MONVOL; 1723 fn = audiohd_set_mongain; 1724 break; 1725 1726 case CTL_RECSRC: 1727 desc.acd_name = AUDIO_CTRL_ID_RECSRC; 1728 desc.acd_type = AUDIO_CTRL_TYPE_ENUM; 1729 desc.acd_minvalue = statep->inmask; 1730 desc.acd_maxvalue = statep->inmask; 1731 desc.acd_flags = RECCTL; 1732 for (int i = 0; audiohd_dtypes[i]; i++) { 1733 desc.acd_enum[i] = audiohd_dtypes[i]; 1734 } 1735 fn = audiohd_set_recsrc; 1736 break; 1737 } 1738 1739 pc->val = val; 1740 pc->ctrl = audio_dev_add_control(statep->adev, &desc, 1741 audiohd_get_value, fn, pc); 1742 1743 return (pc); 1744 } 1745 1746 static void 1747 audiohd_free_ctrl(audiohd_ctrl_t *pc) 1748 { 1749 if (pc == NULL) 1750 return; 1751 if (pc->ctrl) 1752 audio_dev_del_control(pc->ctrl); 1753 kmem_free(pc, sizeof (*pc)); 1754 } 1755 1756 static void 1757 audiohd_del_controls(audiohd_state_t *statep) 1758 { 1759 int i; 1760 for (i = 0; i < CTRL_NUM; i++) { 1761 if (statep->controls[i]) 1762 audiohd_free_ctrl(statep->controls[i]); 1763 } 1764 } 1765 1766 static int 1767 audiohd_add_controls(audiohd_state_t *statep) 1768 { 1769 int i, j; 1770 audiohd_path_t *path; 1771 wid_t wid; 1772 audiohd_pin_t *pin; 1773 audiohd_widget_t *widget, *w; 1774 hda_codec_t *codec; 1775 audiohd_pin_color_t clr; 1776 1777 #define ADD_CTRL(ID, VAL) \ 1778 if (statep->controls[ID] == NULL) \ 1779 statep->controls[ID] = audiohd_alloc_ctrl(statep, ID, VAL);\ 1780 if (statep->controls[ID] == NULL) { \ 1781 audio_dev_warn(statep->adev, \ 1782 "Unable to allocate %s control", #ID); \ 1783 return (DDI_FAILURE); \ 1784 } 1785 1786 for (i = 0; i < statep->pathnum; i++) { 1787 path = statep->path[i]; 1788 if (!path || path->path_type != PLAY) 1789 continue; 1790 /* 1791 * Firstly we check if all the DACs on the play paths 1792 * have amplifiers. If any of them doesn't have, we just use 1793 * the soft volume control to adjust the PCM volume. 1794 */ 1795 wid = path->adda_wid; 1796 w = path->codec->widget[wid]; 1797 if (!w->outamp_cap) { 1798 (void) audio_dev_add_soft_volume(statep->adev); 1799 statep->soft_volume = B_TRUE; 1800 break; 1801 } 1802 } 1803 /* 1804 * if all the DACs on the play paths have the amplifiers, we use DACs' 1805 * amplifiers to adjust volume. 1806 */ 1807 if (!statep->soft_volume) { 1808 ADD_CTRL(CTL_VOLUME, 0x4b); 1809 } 1810 /* allocate other controls */ 1811 for (i = 0; i < statep->pathnum; i++) { 1812 path = statep->path[i]; 1813 if (!path) 1814 continue; 1815 codec = path->codec; 1816 for (j = 0; j < path->pin_nums; j++) { 1817 wid = path->pin_wid[j]; 1818 widget = codec->widget[wid]; 1819 pin = (audiohd_pin_t *)widget->priv; 1820 if (pin->device == DTYPE_SPEAKER) { 1821 ADD_CTRL(CTL_SPEAKER, 0x4b4b); 1822 } else if (pin->device == DTYPE_HP_OUT) { 1823 ADD_CTRL(CTL_HEADPHONE, 0x4b4b); 1824 } else if (pin->device == DTYPE_LINE_IN) { 1825 ADD_CTRL(CTL_LINEIN, 0x3232); 1826 } else if (pin->device == DTYPE_MIC_IN) { 1827 ADD_CTRL(CTL_MIC, 0x3232); 1828 } else if (pin->device == DTYPE_CD) { 1829 ADD_CTRL(CTL_CD, 0x3232); 1830 } 1831 clr = (pin->config >> AUDIOHD_PIN_CLR_OFF) & 1832 AUDIOHD_PIN_CLR_MASK; 1833 if (clr == AUDIOHD_PIN_GREEN) { 1834 ADD_CTRL(CTL_FRONT, 0x4b4b); 1835 } else if (clr == AUDIOHD_PIN_BLACK && 1836 pin->device != DTYPE_HP_OUT && 1837 pin->device != DTYPE_MIC_IN) { 1838 ADD_CTRL(CTL_REAR, 0x4b4b); 1839 } else if (clr == AUDIOHD_PIN_ORANGE) { 1840 ADD_CTRL(CTL_CENTER, 0x4b); 1841 ADD_CTRL(CTL_LFE, 0x4b); 1842 } else if (clr == AUDIOHD_PIN_GREY) { 1843 ADD_CTRL(CTL_SURROUND, 0x4b4b); 1844 } 1845 } 1846 } 1847 1848 if (!statep->monitor_unsupported) { 1849 ADD_CTRL(CTL_MONGAIN, 0); 1850 } 1851 1852 ADD_CTRL(CTL_RECSRC, (1U << DTYPE_MIC_IN)); 1853 1854 audiohd_configure_output(statep); 1855 audiohd_configure_input(statep); 1856 1857 return (DDI_SUCCESS); 1858 } 1859 1860 /* 1861 * quiesce(9E) entry point. 1862 * 1863 * This function is called when the system is single-threaded at high 1864 * PIL with preemption disabled. Therefore, this function must not be 1865 * blocked. 1866 * 1867 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 1868 * DDI_FAILURE indicates an error condition and should almost never happen. 1869 */ 1870 static int 1871 audiohd_quiesce(dev_info_t *dip) 1872 { 1873 audiohd_state_t *statep; 1874 1875 statep = ddi_get_driver_private(dip); 1876 1877 audiohd_stop_dma(statep); 1878 audiohd_disable_intr(statep); 1879 1880 return (DDI_SUCCESS); 1881 } 1882 /* 1883 * audiohd_init_state() 1884 * 1885 * Description 1886 * This routine initailizes soft state of driver instance, 1887 * also, it requests an interrupt cookie and initializes 1888 * mutex for soft state. 1889 */ 1890 /*ARGSUSED*/ 1891 static int 1892 audiohd_init_state(audiohd_state_t *statep, dev_info_t *dip) 1893 { 1894 audio_dev_t *adev; 1895 1896 statep->hda_dip = dip; 1897 1898 if ((adev = audio_dev_alloc(dip, 0)) == NULL) { 1899 cmn_err(CE_WARN, "unable to allocate audio dev"); 1900 return (AUDIO_FAILURE); 1901 } 1902 statep->adev = adev; 1903 1904 /* set device information */ 1905 audio_dev_set_description(adev, AUDIOHD_DEV_CONFIG); 1906 audio_dev_set_version(adev, AUDIOHD_DEV_VERSION); 1907 1908 if (ddi_get_iblock_cookie(dip, (uint_t)0, &statep->hda_intr_cookie) != 1909 DDI_SUCCESS) { 1910 audio_dev_warn(statep->adev, 1911 "cannot get iblock cookie"); 1912 goto error; 1913 } 1914 mutex_init(&statep->hda_mutex, NULL, 1915 MUTEX_DRIVER, statep->hda_intr_cookie); 1916 1917 statep->hda_rirb_rp = 0; 1918 1919 return (AUDIO_SUCCESS); 1920 error: 1921 if (statep->adev != NULL) 1922 audio_dev_free(statep->adev); 1923 return (AUDIO_FAILURE); 1924 } /* audiohd_init_state() */ 1925 1926 /* 1927 * audiohd_init_pci() 1928 * 1929 * Description 1930 * enable driver to access PCI configure space and memory 1931 * I/O space. 1932 */ 1933 static int 1934 audiohd_init_pci(audiohd_state_t *statep, ddi_device_acc_attr_t *acc_attr) 1935 { 1936 uint16_t cmdreg; 1937 uint16_t vid; 1938 uint8_t cTmp; 1939 dev_info_t *dip = statep->hda_dip; 1940 audio_dev_t *ahandle = statep->adev; 1941 1942 if (pci_config_setup(dip, &statep->hda_pci_handle) == DDI_FAILURE) { 1943 audio_dev_warn(ahandle, 1944 "pci config mapping failed"); 1945 goto err_init_pci_exit1; 1946 } 1947 1948 if (ddi_regs_map_setup(dip, 1, &statep->hda_reg_base, 0, 1949 0, acc_attr, &statep->hda_reg_handle) != DDI_SUCCESS) { 1950 audio_dev_warn(ahandle, 1951 "memory I/O mapping failed"); 1952 goto err_init_pci_exit2; 1953 } 1954 1955 /* 1956 * HD audio control uses memory I/O only, enable it here. 1957 */ 1958 cmdreg = pci_config_get16(statep->hda_pci_handle, PCI_CONF_COMM); 1959 pci_config_put16(statep->hda_pci_handle, PCI_CONF_COMM, 1960 cmdreg | PCI_COMM_MAE | PCI_COMM_ME); 1961 1962 vid = pci_config_get16(statep->hda_pci_handle, PCI_CONF_VENID); 1963 switch (vid) { 1964 1965 case AUDIOHD_VID_INTEL: 1966 /* 1967 * Currently, Intel (G)MCH and ICHx chipsets support PCI 1968 * Express QoS. It implemenets two VCs(virtual channels) 1969 * and allows OS software to map 8 traffic classes to the 1970 * two VCs. Some BIOSes initialize HD audio hardware to 1971 * use TC7 (traffic class 7) and to map TC7 to VC1 as Intel 1972 * recommended. However, solaris doesn't support PCI express 1973 * QoS yet. As a result, this driver can not work for those 1974 * hardware without touching PCI express control registers. 1975 * Here, we set TCSEL to 0 so as to use TC0/VC0 (VC0 is 1976 * always enabled and TC0 is always mapped to VC0) for all 1977 * Intel HD audio controllers. 1978 */ 1979 cTmp = pci_config_get8(statep->hda_pci_handle, 1980 AUDIOHD_INTEL_PCI_TCSEL); 1981 pci_config_put8(statep->hda_pci_handle, 1982 AUDIOHD_INTEL_PCI_TCSEL, (cTmp & AUDIOHD_INTEL_TCS_MASK)); 1983 break; 1984 1985 case AUDIOHD_VID_ATI: 1986 /* 1987 * Refer to ATI SB450 datesheet. We set snoop for SB450 1988 * like hardware. 1989 */ 1990 cTmp = pci_config_get8(statep->hda_pci_handle, 1991 AUDIOHD_ATI_PCI_MISC2); 1992 pci_config_put8(statep->hda_pci_handle, AUDIOHD_ATI_PCI_MISC2, 1993 (cTmp & AUDIOHD_ATI_MISC2_MASK) | AUDIOHD_ATI_MISC2_SNOOP); 1994 break; 1995 /* 1996 * Refer to the datasheet, we set snoop for NVIDIA 1997 * like hardware 1998 */ 1999 case AUDIOHD_VID_NVIDIA: 2000 cTmp = pci_config_get8(statep->hda_pci_handle, 2001 AUDIOHD_CORB_SIZE_OFF); 2002 pci_config_put8(statep->hda_pci_handle, AUDIOHD_CORB_SIZE_OFF, 2003 cTmp | AUDIOHD_NVIDIA_SNOOP); 2004 break; 2005 2006 default: 2007 break; 2008 } 2009 2010 return (AUDIO_SUCCESS); 2011 2012 err_init_pci_exit2: 2013 pci_config_teardown(&statep->hda_pci_handle); 2014 2015 err_init_pci_exit1: 2016 return (AUDIO_FAILURE); 2017 2018 } /* audiohd_init_pci() */ 2019 2020 2021 /* 2022 * audiohd_fini_pci() 2023 * 2024 * Description 2025 * Release mapping for PCI configure space. 2026 */ 2027 static void 2028 audiohd_fini_pci(audiohd_state_t *statep) 2029 { 2030 if (statep->hda_reg_handle != NULL) { 2031 ddi_regs_map_free(&statep->hda_reg_handle); 2032 statep->hda_reg_handle = NULL; 2033 } 2034 2035 if (statep->hda_pci_handle != NULL) { 2036 pci_config_teardown(&statep->hda_pci_handle); 2037 statep->hda_pci_handle = NULL; 2038 } 2039 2040 } /* audiohd_fini_pci() */ 2041 2042 /* 2043 * audiohd_stop_dma() 2044 * 2045 * Description 2046 * Stop all DMA behaviors of controllers, for command I/O 2047 * and each audio stream. 2048 */ 2049 static void 2050 audiohd_stop_dma(audiohd_state_t *statep) 2051 { 2052 int i; 2053 uint_t base; 2054 uint8_t bTmp; 2055 2056 AUDIOHD_REG_SET8(AUDIOHD_REG_CORBCTL, 0); 2057 AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBCTL, 0); 2058 2059 base = AUDIOHD_REG_SD_BASE; 2060 for (i = 0; i < statep->hda_streams_nums; i++) { 2061 bTmp = AUDIOHD_REG_GET8(base + AUDIOHD_SDREG_OFFSET_CTL); 2062 2063 /* for input/output stream, it is the same */ 2064 bTmp &= ~AUDIOHDR_RIRBCTL_DMARUN; 2065 2066 AUDIOHD_REG_SET8(base + AUDIOHD_SDREG_OFFSET_CTL, bTmp); 2067 base += AUDIOHD_REG_SD_LEN; 2068 } 2069 2070 /* wait 40us for stream DMA to stop */ 2071 drv_usecwait(40); 2072 2073 } /* audiohd_stop_dma() */ 2074 2075 /* 2076 * audiohd_reset_controller() 2077 * 2078 * Description: 2079 * This routine is just used to reset controller and 2080 * CODEC as well by HW reset bit in global control 2081 * register of HD controller. 2082 */ 2083 static int 2084 audiohd_reset_controller(audiohd_state_t *statep) 2085 { 2086 int i; 2087 uint16_t sTmp; 2088 uint32_t gctl; 2089 2090 /* Reset Status register but preserve the first bit */ 2091 sTmp = AUDIOHD_REG_GET16(AUDIOHD_REG_STATESTS); 2092 AUDIOHD_REG_SET16(AUDIOHD_REG_STATESTS, sTmp & 0x8000); 2093 2094 /* reset controller */ 2095 gctl = AUDIOHD_REG_GET32(AUDIOHD_REG_GCTL); 2096 gctl &= ~AUDIOHDR_GCTL_CRST; 2097 AUDIOHD_REG_SET32(AUDIOHD_REG_GCTL, gctl); /* entering reset state */ 2098 for (i = 0; i < AUDIOHD_RETRY_TIMES; i++) { 2099 /* Empirical testing time: 150 */ 2100 drv_usecwait(150); 2101 gctl = AUDIOHD_REG_GET32(AUDIOHD_REG_GCTL); 2102 if ((gctl & AUDIOHDR_GCTL_CRST) == 0) 2103 break; 2104 } 2105 2106 if ((gctl & AUDIOHDR_GCTL_CRST) != 0) { 2107 audio_dev_warn(statep->adev, 2108 "failed to enter reset state"); 2109 return (AUDIO_FAILURE); 2110 } 2111 2112 /* Empirical testing time:300 */ 2113 drv_usecwait(300); 2114 2115 /* exit reset state */ 2116 AUDIOHD_REG_SET32(AUDIOHD_REG_GCTL, gctl | AUDIOHDR_GCTL_CRST); 2117 2118 for (i = 0; i < AUDIOHD_RETRY_TIMES; i++) { 2119 /* Empirical testing time: 150, which works well */ 2120 drv_usecwait(150); 2121 gctl = AUDIOHD_REG_GET32(AUDIOHD_REG_GCTL); 2122 if (gctl & AUDIOHDR_GCTL_CRST) 2123 break; 2124 } 2125 2126 if ((gctl & AUDIOHDR_GCTL_CRST) == 0) { 2127 audio_dev_warn(statep->adev, 2128 "failed to exit reset state"); 2129 return (AUDIO_FAILURE); 2130 } 2131 2132 /* HD spec requires to wait 250us at least. we use 500us */ 2133 drv_usecwait(500); 2134 2135 /* enable unsolicited response */ 2136 AUDIOHD_REG_SET32(AUDIOHD_REG_GCTL, 2137 gctl | AUDIOHDR_GCTL_URESPE); 2138 2139 return (AUDIO_SUCCESS); 2140 2141 } /* audiohd_reset_controller() */ 2142 2143 /* 2144 * audiohd_alloc_dma_mem() 2145 * 2146 * Description: 2147 * This is an utility routine. It is used to allocate DMA 2148 * memory. 2149 */ 2150 static int 2151 audiohd_alloc_dma_mem(audiohd_state_t *statep, audiohd_dma_t *pdma, 2152 size_t memsize, ddi_dma_attr_t *dma_attr_p, uint_t dma_flags) 2153 { 2154 ddi_dma_cookie_t cookie; 2155 uint_t count; 2156 dev_info_t *dip = statep->hda_dip; 2157 audio_dev_t *ahandle = statep->adev; 2158 2159 if (ddi_dma_alloc_handle(dip, dma_attr_p, DDI_DMA_SLEEP, 2160 NULL, &pdma->ad_dmahdl) != DDI_SUCCESS) { 2161 audio_dev_warn(ahandle, 2162 "ddi_dma_alloc_handle failed"); 2163 goto error_alloc_dma_exit1; 2164 } 2165 2166 if (ddi_dma_mem_alloc(pdma->ad_dmahdl, memsize, &hda_dev_accattr, 2167 dma_flags & (DDI_DMA_CONSISTENT | DDI_DMA_STREAMING), 2168 DDI_DMA_SLEEP, NULL, 2169 (caddr_t *)&pdma->ad_vaddr, &pdma->ad_real_sz, 2170 &pdma->ad_acchdl) != DDI_SUCCESS) { 2171 audio_dev_warn(ahandle, 2172 "ddi_dma_mem_alloc failed"); 2173 goto error_alloc_dma_exit2; 2174 } 2175 2176 if (ddi_dma_addr_bind_handle(pdma->ad_dmahdl, NULL, 2177 (caddr_t)pdma->ad_vaddr, pdma->ad_real_sz, dma_flags, 2178 DDI_DMA_SLEEP, NULL, &cookie, &count) != DDI_DMA_MAPPED) { 2179 audio_dev_warn(ahandle, 2180 "ddi_dma_addr_bind_handle failed"); 2181 goto error_alloc_dma_exit3; 2182 } 2183 2184 pdma->ad_paddr = (uint64_t)(cookie.dmac_laddress); 2185 pdma->ad_req_sz = memsize; 2186 2187 return (AUDIO_SUCCESS); 2188 2189 error_alloc_dma_exit3: 2190 ddi_dma_mem_free(&pdma->ad_acchdl); 2191 2192 error_alloc_dma_exit2: 2193 ddi_dma_free_handle(&pdma->ad_dmahdl); 2194 2195 error_alloc_dma_exit1: 2196 return (AUDIO_FAILURE); 2197 2198 } /* audiohd_alloc_dma_mem() */ 2199 2200 /* 2201 * audiohd_release_dma_mem() 2202 * 2203 * Description: 2204 * Release DMA memory. 2205 */ 2206 2207 static void 2208 audiohd_release_dma_mem(audiohd_dma_t *pdma) 2209 { 2210 if (pdma->ad_dmahdl != NULL) { 2211 (void) ddi_dma_unbind_handle(pdma->ad_dmahdl); 2212 } 2213 2214 if (pdma->ad_acchdl != NULL) { 2215 ddi_dma_mem_free(&pdma->ad_acchdl); 2216 pdma->ad_acchdl = NULL; 2217 } 2218 2219 if (pdma->ad_dmahdl != NULL) { 2220 ddi_dma_free_handle(&pdma->ad_dmahdl); 2221 pdma->ad_dmahdl = NULL; 2222 } 2223 2224 } /* audiohd_release_dma_mem() */ 2225 2226 /* 2227 * audiohd_reinit_hda() 2228 * 2229 * Description: 2230 * This routine is used to re-initialize HD controller and codec. 2231 */ 2232 static int 2233 audiohd_reinit_hda(audiohd_state_t *statep) 2234 { 2235 uint64_t addr; 2236 2237 /* set PCI configure space in case it's not restored OK */ 2238 (void) audiohd_init_pci(statep, &hda_dev_accattr); 2239 2240 /* reset controller */ 2241 if (audiohd_reset_controller(statep) != AUDIO_SUCCESS) 2242 return (AUDIO_FAILURE); 2243 AUDIOHD_REG_SET32(AUDIOHD_REG_SYNC, 0); /* needn't sync stream */ 2244 2245 /* Initialize controller RIRB */ 2246 addr = statep->hda_dma_rirb.ad_paddr; 2247 AUDIOHD_REG_SET32(AUDIOHD_REG_RIRBLBASE, (uint32_t)addr); 2248 AUDIOHD_REG_SET32(AUDIOHD_REG_RIRBUBASE, 2249 (uint32_t)(addr >> 32)); 2250 AUDIOHD_REG_SET16(AUDIOHD_REG_RIRBWP, AUDIOHDR_RIRBWP_RESET); 2251 AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBSIZE, AUDIOHDR_RIRBSZ_256); 2252 AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBCTL, AUDIOHDR_RIRBCTL_DMARUN | 2253 AUDIOHDR_RIRBCTL_RINTCTL); 2254 2255 /* Initialize controller CORB */ 2256 addr = statep->hda_dma_corb.ad_paddr; 2257 AUDIOHD_REG_SET16(AUDIOHD_REG_CORBRP, AUDIOHDR_CORBRP_RESET); 2258 AUDIOHD_REG_SET32(AUDIOHD_REG_CORBLBASE, (uint32_t)addr); 2259 AUDIOHD_REG_SET32(AUDIOHD_REG_CORBUBASE, 2260 (uint32_t)(addr >> 32)); 2261 AUDIOHD_REG_SET8(AUDIOHD_REG_CORBSIZE, AUDIOHDR_CORBSZ_256); 2262 AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, 0); 2263 AUDIOHD_REG_SET16(AUDIOHD_REG_CORBRP, 0); 2264 AUDIOHD_REG_SET8(AUDIOHD_REG_CORBCTL, AUDIOHDR_CORBCTL_DMARUN); 2265 2266 audiohd_restore_codec_gpio(statep); 2267 audiohd_restore_path(statep); 2268 audiohd_init_path(statep); 2269 2270 return (AUDIO_SUCCESS); 2271 } /* audiohd_reinit_hda */ 2272 2273 /* 2274 * audiohd_init_controller() 2275 * 2276 * Description: 2277 * This routine is used to initialize HD controller. It 2278 * allocates DMA memory for CORB/RIRB, buffer descriptor 2279 * list and cylic data buffer for both play and record 2280 * stream. 2281 */ 2282 static int 2283 audiohd_init_controller(audiohd_state_t *statep) 2284 { 2285 uint64_t addr; 2286 uint16_t gcap; 2287 int retval; 2288 2289 ddi_dma_attr_t dma_attr = { 2290 DMA_ATTR_V0, /* version */ 2291 0, /* addr_lo */ 2292 0xffffffffffffffffULL, /* addr_hi */ 2293 0x00000000ffffffffULL, /* count_max */ 2294 128, /* 128-byte alignment as HD spec */ 2295 0xfff, /* burstsize */ 2296 1, /* minxfer */ 2297 0xffffffff, /* maxxfer */ 2298 0xffffffff, /* seg */ 2299 1, /* sgllen */ 2300 1, /* granular */ 2301 0 /* flags */ 2302 }; 2303 2304 gcap = AUDIOHD_REG_GET16(AUDIOHD_REG_GCAP); 2305 2306 /* 2307 * If the device doesn't support 64-bit DMA, we should not 2308 * allocate DMA memory from 4G above 2309 */ 2310 if ((gcap & AUDIOHDR_GCAP_64OK) == 0) 2311 dma_attr.dma_attr_addr_hi = 0xffffffffUL; 2312 2313 statep->hda_input_streams = (gcap & AUDIOHDR_GCAP_INSTREAMS) >> 2314 AUDIOHD_INSTR_NUM_OFF; 2315 statep->hda_output_streams = (gcap & AUDIOHDR_GCAP_OUTSTREAMS) >> 2316 AUDIOHD_OUTSTR_NUM_OFF; 2317 statep->hda_streams_nums = statep->hda_input_streams + 2318 statep->hda_output_streams; 2319 2320 2321 statep->hda_record_regbase = AUDIOHD_REG_SD_BASE; 2322 statep->hda_play_regbase = AUDIOHD_REG_SD_BASE + AUDIOHD_REG_SD_LEN * 2323 statep->hda_input_streams; 2324 2325 2326 /* stop all dma before starting to reset controller */ 2327 audiohd_stop_dma(statep); 2328 2329 if (audiohd_reset_controller(statep) != AUDIO_SUCCESS) 2330 return (AUDIO_FAILURE); 2331 2332 /* check codec */ 2333 statep->hda_codec_mask = AUDIOHD_REG_GET16(AUDIOHD_REG_STATESTS); 2334 if (! statep->hda_codec_mask) { 2335 audio_dev_warn(statep->adev, 2336 "no codec exists"); 2337 goto err_init_ctlr_exit1; 2338 } 2339 2340 /* allocate DMA for CORB */ 2341 retval = audiohd_alloc_dma_mem(statep, &statep->hda_dma_corb, 2342 AUDIOHD_CDBIO_CORB_LEN, &dma_attr, 2343 DDI_DMA_WRITE | DDI_DMA_STREAMING); 2344 if (retval != AUDIO_SUCCESS) { 2345 audio_dev_warn(statep->adev, 2346 "failed to alloc DMA for CORB"); 2347 goto err_init_ctlr_exit1; 2348 } 2349 2350 /* allocate DMA for RIRB */ 2351 retval = audiohd_alloc_dma_mem(statep, &statep->hda_dma_rirb, 2352 AUDIOHD_CDBIO_RIRB_LEN, &dma_attr, 2353 DDI_DMA_READ | DDI_DMA_STREAMING); 2354 if (retval != AUDIO_SUCCESS) { 2355 audio_dev_warn(statep->adev, 2356 "failed to alloc DMA for RIRB"); 2357 goto err_init_ctlr_exit2; 2358 } 2359 2360 2361 AUDIOHD_REG_SET32(AUDIOHD_REG_SYNC, 0); /* needn't sync stream */ 2362 2363 /* Initialize RIRB */ 2364 addr = statep->hda_dma_rirb.ad_paddr; 2365 AUDIOHD_REG_SET32(AUDIOHD_REG_RIRBLBASE, (uint32_t)addr); 2366 AUDIOHD_REG_SET32(AUDIOHD_REG_RIRBUBASE, 2367 (uint32_t)(addr >> 32)); 2368 AUDIOHD_REG_SET16(AUDIOHD_REG_RIRBWP, AUDIOHDR_RIRBWP_RESET); 2369 AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBSIZE, AUDIOHDR_RIRBSZ_256); 2370 AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBCTL, AUDIOHDR_RIRBCTL_DMARUN | 2371 AUDIOHDR_RIRBCTL_RINTCTL); 2372 2373 /* initialize CORB */ 2374 addr = statep->hda_dma_corb.ad_paddr; 2375 AUDIOHD_REG_SET16(AUDIOHD_REG_CORBRP, AUDIOHDR_CORBRP_RESET); 2376 AUDIOHD_REG_SET32(AUDIOHD_REG_CORBLBASE, (uint32_t)addr); 2377 AUDIOHD_REG_SET32(AUDIOHD_REG_CORBUBASE, 2378 (uint32_t)(addr >> 32)); 2379 AUDIOHD_REG_SET8(AUDIOHD_REG_CORBSIZE, AUDIOHDR_CORBSZ_256); 2380 AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, 0); 2381 AUDIOHD_REG_SET16(AUDIOHD_REG_CORBRP, 0); 2382 AUDIOHD_REG_SET8(AUDIOHD_REG_CORBCTL, AUDIOHDR_CORBCTL_DMARUN); 2383 2384 return (AUDIO_SUCCESS); 2385 2386 err_init_ctlr_exit3: 2387 audiohd_release_dma_mem(&(statep->hda_dma_rirb)); 2388 2389 err_init_ctlr_exit2: 2390 audiohd_release_dma_mem(&(statep->hda_dma_corb)); 2391 2392 err_init_ctlr_exit1: 2393 return (AUDIO_FAILURE); 2394 2395 } /* audiohd_init_controller() */ 2396 2397 /* 2398 * audiohd_fini_controller() 2399 * 2400 * Description: 2401 * Releases DMA memory allocated in audiohd_init_controller() 2402 */ 2403 static void 2404 audiohd_fini_controller(audiohd_state_t *statep) 2405 { 2406 audiohd_stop_dma(statep); 2407 audiohd_release_dma_mem(&statep->hda_dma_rirb); 2408 audiohd_release_dma_mem(&statep->hda_dma_corb); 2409 2410 } /* audiohd_fini_controller() */ 2411 2412 /* 2413 * audiohd_get_conns_from_entry() 2414 * 2415 * Description: 2416 * Get connection list from every entry for a widget 2417 */ 2418 static void 2419 audiohd_get_conns_from_entry(hda_codec_t *codec, audiohd_widget_t *widget, 2420 uint32_t entry, audiohd_entry_prop_t *prop) 2421 { 2422 int i, k, num; 2423 wid_t input_wid; 2424 2425 for (i = 0; i < prop->conns_per_entry && 2426 widget->nconns < prop->conn_len; 2427 i++, entry >>= prop->bits_per_conn) { 2428 ASSERT(widget->nconns < AUDIOHD_MAX_CONN); 2429 input_wid = entry & prop->mask_wid; 2430 if (entry & prop->mask_range) { 2431 if (widget->nconns == 0) { 2432 if (input_wid < codec->first_wid || 2433 (input_wid > codec->last_wid)) { 2434 break; 2435 } 2436 widget->avail_conn[widget->nconns++] = 2437 input_wid; 2438 } else { 2439 for (k = widget->avail_conn[widget->nconns-1] + 2440 1; k <= input_wid; k++) { 2441 ASSERT(widget->nconns < 2442 AUDIOHD_MAX_CONN); 2443 if (k < codec->first_wid || 2444 (k > codec->last_wid)) { 2445 break; 2446 } else { 2447 num = widget->nconns; 2448 widget->avail_conn[num] = k; 2449 widget->nconns++; 2450 } 2451 } 2452 } 2453 } else { 2454 if ((codec->first_wid <= input_wid) && (input_wid <= 2455 codec->last_wid)) 2456 widget->avail_conn[widget->nconns++] = 2457 input_wid; 2458 } 2459 } 2460 } 2461 2462 /* 2463 * audiohd_get_conns() 2464 * 2465 * Description: 2466 * Get all connection list for a widget. The connection list is used for 2467 * build output path, input path, and monitor path 2468 */ 2469 static void 2470 audiohd_get_conns(hda_codec_t *codec, wid_t wid) 2471 { 2472 audiohd_state_t *statep = codec->soft_statep; 2473 audiohd_widget_t *widget = codec->widget[wid]; 2474 uint8_t caddr = codec->index; 2475 uint32_t entry; 2476 audiohd_entry_prop_t prop; 2477 wid_t input_wid; 2478 int i; 2479 2480 prop.conn_len = audioha_codec_verb_get(statep, caddr, wid, 2481 AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_CONNLIST_LEN); 2482 2483 if (prop.conn_len & AUDIOHD_FORM_MASK) { 2484 prop.conns_per_entry = 2; 2485 prop.bits_per_conn = 16; 2486 prop.mask_range = 0x00008000; 2487 prop.mask_wid = 0x00007fff; 2488 } else { 2489 prop.conns_per_entry = 4; 2490 prop.bits_per_conn = 8; 2491 prop.mask_range = 0x00000080; 2492 prop.mask_wid = 0x0000007f; 2493 } 2494 prop.conn_len &= AUDIOHD_LEN_MASK; 2495 2496 /* 2497 * This should not happen since the ConnectionList bit of 2498 * widget capabilities already told us that this widget 2499 * has a connection list 2500 */ 2501 if (prop.conn_len == 0) { 2502 widget->nconns = 0; 2503 cmn_err(CE_WARN, "node %d has 0 connections\n", wid); 2504 return; 2505 } 2506 2507 if (prop.conn_len == 1) { 2508 entry = audioha_codec_verb_get(statep, caddr, 2509 wid, AUDIOHDC_VERB_GET_CONN_LIST_ENT, 0); 2510 input_wid = entry & prop.mask_wid; 2511 if ((input_wid < codec->first_wid) || 2512 (input_wid > codec->last_wid)) { 2513 return; 2514 } 2515 widget->avail_conn[0] = input_wid; 2516 widget->nconns = 1; 2517 return; 2518 } 2519 widget->nconns = 0; 2520 for (i = 0; i < prop.conn_len; i += prop.conns_per_entry) { 2521 entry = audioha_codec_verb_get(statep, caddr, wid, 2522 AUDIOHDC_VERB_GET_CONN_LIST_ENT, i); 2523 audiohd_get_conns_from_entry(codec, widget, entry, &prop); 2524 } 2525 } 2526 2527 /* 2528 * Read PinCapabilities & default configuration 2529 */ 2530 static void 2531 audiohd_get_pin_config(audiohd_widget_t *widget) 2532 { 2533 hda_codec_t *codec = widget->codec; 2534 audiohd_state_t *statep = codec->soft_statep; 2535 audiohd_pin_t *pin, *prev, *p; 2536 2537 int caddr = codec->index; 2538 wid_t wid = widget->wid_wid; 2539 uint32_t cap, config, pinctrl; 2540 uint8_t urctrl, vrefbits; 2541 2542 cap = audioha_codec_verb_get(statep, caddr, wid, 2543 AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_PIN_CAP); 2544 config = audioha_codec_verb_get(statep, caddr, 2545 wid, AUDIOHDC_VERB_GET_DEFAULT_CONF, 0); 2546 pinctrl = audioha_codec_verb_get(statep, caddr, 2547 wid, AUDIOHDC_VERB_GET_PIN_CTRL, 0); 2548 2549 pin = (audiohd_pin_t *)kmem_zalloc(sizeof (audiohd_pin_t), KM_SLEEP); 2550 widget->priv = pin; 2551 2552 /* 2553 * If the pin has no physical connection for port, 2554 * we won't link it to pin linkage list ??? 2555 */ 2556 if (((config >> AUDIOHD_PIN_CON_STEP) & AUDIOHD_PIN_CON_MASK) == 0x1) { 2557 pin->no_phys_conn = 1; 2558 } 2559 2560 /* bit 4:3 are reserved, read-modify-write is needed */ 2561 pin->ctrl = pinctrl & AUDIOHD_PIN_IO_MASK; 2562 pin->wid = wid; 2563 pin->cap = cap; 2564 pin->config = config; 2565 pin->num = 0; 2566 pin->finish = 0; 2567 2568 vrefbits = (cap >> AUDIOHD_PIN_VREF_OFF) & AUDIOHD_PIN_VREF_MASK; 2569 if (vrefbits & AUDIOHD_PIN_VREF_L1) 2570 pin->vrefvalue = 0x5; 2571 else if (vrefbits & AUDIOHD_PIN_VREF_L2) 2572 pin->vrefvalue = 0x4; 2573 else if (vrefbits & AUDIOHD_PIN_VREF_L3) 2574 pin->vrefvalue = 0x2; 2575 else 2576 pin->vrefvalue = 0x1; 2577 2578 pin->seq = config & AUDIOHD_PIN_SEQ_MASK; 2579 pin->assoc = (config & AUDIOHD_PIN_ASO_MASK) >> AUDIOHD_PIN_ASO_OFF; 2580 pin->device = (config & AUDIOHD_PIN_DEV_MASK) >> AUDIOHD_PIN_DEV_OFF; 2581 2582 /* enable the unsolicited response of the pin */ 2583 if ((widget->widget_cap & AUDIOHD_URCAP_MASK) && 2584 (pin->cap & AUDIOHD_DTCCAP_MASK) && 2585 ((pin->device == DTYPE_LINEOUT) || 2586 (pin->device == DTYPE_SPDIF_OUT) || 2587 (pin->device == DTYPE_HP_OUT) || 2588 (pin->device == DTYPE_MIC_IN))) { 2589 urctrl = (uint8_t)(1 << (AUDIOHD_UR_ENABLE_OFF - 1)); 2590 urctrl |= (wid & AUDIOHD_UR_TAG_MASK); 2591 (void) audioha_codec_verb_get(statep, caddr, 2592 wid, AUDIOHDC_VERB_SET_URCTRL, urctrl); 2593 } 2594 /* accommodate all the pins in a link list sorted by assoc and seq */ 2595 if (codec->first_pin == NULL) { 2596 codec->first_pin = pin; 2597 } else { 2598 prev = NULL; 2599 p = codec->first_pin; 2600 while (p) { 2601 if (p->assoc > pin->assoc) 2602 break; 2603 if ((p->assoc == pin->assoc) && 2604 (p->seq > pin->seq)) 2605 break; 2606 prev = p; 2607 p = p->next; 2608 } 2609 if (prev) { 2610 pin->next = prev->next; 2611 prev->next = pin; 2612 } else { 2613 pin->next = codec->first_pin; 2614 codec->first_pin = pin; 2615 } 2616 } 2617 2618 } /* audiohd_get_pin_config() */ 2619 2620 /* 2621 * audiohd_create_widgets() 2622 * 2623 * Description: 2624 * All widgets are created and stored in an array of codec 2625 */ 2626 static int 2627 audiohd_create_widgets(hda_codec_t *codec) 2628 { 2629 audiohd_widget_t *widget; 2630 audiohd_state_t *statep = codec->soft_statep; 2631 wid_t wid; 2632 uint32_t type, widcap; 2633 int caddr = codec->index; 2634 2635 for (wid = codec->first_wid; 2636 wid <= codec->last_wid; wid++) { 2637 widget = (audiohd_widget_t *) 2638 kmem_zalloc(sizeof (audiohd_widget_t), KM_SLEEP); 2639 codec->widget[wid] = widget; 2640 widget->codec = codec; 2641 widget->selconn = AUDIOHD_NULL_CONN; 2642 2643 widcap = audioha_codec_verb_get(statep, caddr, wid, 2644 AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_AUDIO_WID_CAP); 2645 type = AUDIOHD_WIDCAP_TO_WIDTYPE(widcap); 2646 widget->wid_wid = wid; 2647 widget->type = type; 2648 widget->widget_cap = widcap; 2649 widget->finish = 0; 2650 widget->used = 0; 2651 2652 /* if there's connection list */ 2653 if (widcap & AUDIOHD_WIDCAP_CONNLIST) { 2654 audiohd_get_conns(codec, wid); 2655 } 2656 2657 /* if power control, power it up to D0 state */ 2658 if (widcap & AUDIOHD_WIDCAP_PWRCTRL) { 2659 (void) audioha_codec_verb_get(statep, caddr, wid, 2660 AUDIOHDC_VERB_SET_POWER_STATE, 0); 2661 } 2662 2663 /* 2664 * if this widget has format override, we read it. 2665 * Otherwise, it uses the format of audio function. 2666 */ 2667 if (widcap & AUDIOHD_WIDCAP_FMT_OVRIDE) { 2668 widget->pcm_format = 2669 audioha_codec_verb_get(statep, caddr, wid, 2670 AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_PCM); 2671 } else { 2672 widget->pcm_format = codec->pcm_format; 2673 } 2674 2675 /* 2676 * Input amplifier. Has the widget input amplifier ? 2677 */ 2678 if (widcap & AUDIOHD_WIDCAP_INAMP) { 2679 /* 2680 * if overrided bit is 0, use the default 2681 * amplifier of audio function as HD spec. 2682 * Otherwise, we read it. 2683 */ 2684 if ((widcap & AUDIOHD_WIDCAP_AMP_OVRIDE) == 0) 2685 widget->inamp_cap = codec->inamp_cap; 2686 else 2687 widget->inamp_cap = 2688 audioha_codec_verb_get(statep, caddr, wid, 2689 AUDIOHDC_VERB_GET_PARAM, 2690 AUDIOHDC_PAR_INAMP_CAP); 2691 } else { 2692 widget->inamp_cap = 0; 2693 } 2694 2695 /* 2696 * output amplifier. Has this widget output amplifier ? 2697 */ 2698 if (widcap & AUDIOHD_WIDCAP_OUTAMP) { 2699 if ((widcap & AUDIOHD_WIDCAP_AMP_OVRIDE) == 0) 2700 widget->outamp_cap = codec->outamp_cap; 2701 else 2702 widget->outamp_cap = 2703 audioha_codec_verb_get(statep, caddr, wid, 2704 AUDIOHDC_VERB_GET_PARAM, 2705 AUDIOHDC_PAR_OUTAMP_CAP); 2706 } else { 2707 widget->outamp_cap = 0; 2708 } 2709 2710 switch (type) { 2711 case WTYPE_AUDIO_OUT: 2712 case WTYPE_AUDIO_IN: 2713 case WTYPE_AUDIO_MIX: 2714 case WTYPE_AUDIO_SEL: 2715 case WTYPE_VENDOR: 2716 case WTYPE_POWER: 2717 case WTYPE_VOL_KNOB: 2718 break; 2719 case WTYPE_PIN: 2720 audiohd_get_pin_config(widget); 2721 break; 2722 case WTYPE_BEEP: 2723 break; 2724 default: 2725 break; 2726 } 2727 } 2728 2729 return (DDI_SUCCESS); 2730 2731 } /* audiohd_create_widgets() */ 2732 2733 /* 2734 * audiohd_destroy_widgets() 2735 */ 2736 static void 2737 audiohd_destroy_widgets(hda_codec_t *codec) 2738 { 2739 for (int i = 0; i < AUDIOHD_MAX_WIDGET; i++) { 2740 if (codec->widget[i]) { 2741 kmem_free(codec->widget[i], sizeof (audiohd_widget_t)); 2742 codec->widget[i] = NULL; 2743 } 2744 } 2745 2746 } /* audiohd_destroy_widgets() */ 2747 2748 static void 2749 audiohd_set_codec_info(hda_codec_t *codec) 2750 { 2751 char buf[256]; 2752 2753 switch (codec->vid) { 2754 case 0x10ec0260: 2755 (void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC260"); 2756 break; 2757 case 0x10ec0262: 2758 (void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC262"); 2759 break; 2760 case 0x10ec0268: 2761 (void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC268"); 2762 break; 2763 case 0x10ec0662: 2764 (void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC662"); 2765 break; 2766 case 0x10ec861: 2767 (void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC861"); 2768 break; 2769 case 0x10ec0862: 2770 (void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC862"); 2771 break; 2772 case 0x10ec0880: 2773 (void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC880"); 2774 break; 2775 case 0x10ec0882: 2776 (void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC882"); 2777 break; 2778 case 0x10ec0883: 2779 (void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC883"); 2780 break; 2781 case 0x10ec0885: 2782 (void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC885"); 2783 break; 2784 case 0x10ec0888: 2785 (void) snprintf(buf, sizeof (buf), "Realtek HD codec: ALC888"); 2786 break; 2787 case 0x13f69880: 2788 (void) snprintf(buf, sizeof (buf), "CMedia HD codec: CMI19880"); 2789 break; 2790 case 0x434d4980: 2791 (void) snprintf(buf, sizeof (buf), "CMedia HD codec: CMI19880"); 2792 break; 2793 case 0x11d41981: 2794 (void) snprintf(buf, sizeof (buf), 2795 "Analog Devices HD codec: AD1981"); 2796 break; 2797 case 0x11d41983: 2798 (void) snprintf(buf, sizeof (buf), 2799 "Analog Devices HD codec: AD1983"); 2800 break; 2801 case 0x11d41984: 2802 (void) snprintf(buf, sizeof (buf), 2803 "Analog Devices HD codec: AD1984"); 2804 break; 2805 case 0x11d41986: 2806 (void) snprintf(buf, sizeof (buf), 2807 "Analog Devices HD codec: AD1986A"); 2808 break; 2809 case 0x11d41988: 2810 (void) snprintf(buf, sizeof (buf), 2811 "Analog Devices HD codec: AD1988A"); 2812 break; 2813 case 0x11d4198b: 2814 (void) snprintf(buf, sizeof (buf), 2815 "Analog Devices HD codec: AD1988B"); 2816 break; 2817 case 0x83847690: 2818 (void) snprintf(buf, sizeof (buf), 2819 "Sigmatel HD codec: STAC9200"); 2820 break; 2821 case 0x838476a0: 2822 (void) snprintf(buf, sizeof (buf), 2823 "Sigmatel HD codec: STAC9205"); 2824 break; 2825 case 0x838476a1: 2826 (void) snprintf(buf, sizeof (buf), 2827 "Sigmatel HD codec: STAC9205D"); 2828 break; 2829 case 0x838476a2: 2830 (void) snprintf(buf, sizeof (buf), 2831 "Sigmatel HD codec: STAC9204"); 2832 break; 2833 case 0x838476a3: 2834 (void) snprintf(buf, sizeof (buf), 2835 "Sigmatel HD codec: STAC9204D"); 2836 break; 2837 case 0x83847880: 2838 (void) snprintf(buf, sizeof (buf), 2839 "Sigmatel HD codec: STAC9220 A1"); 2840 break; 2841 case 0x83847882: 2842 (void) snprintf(buf, sizeof (buf), 2843 "Sigmatel HD codec: STAC9220 A2"); 2844 break; 2845 case 0x83847680: 2846 (void) snprintf(buf, sizeof (buf), 2847 "Sigmatel HD codec: STAC9221 A1"); 2848 break; 2849 case 0x83847681: 2850 (void) snprintf(buf, sizeof (buf), 2851 "Sigmatel HD codec: STAC9220 D"); 2852 break; 2853 case 0x83847682: 2854 (void) snprintf(buf, sizeof (buf), 2855 "Sigmatel HD codec: STAC9221"); 2856 break; 2857 case 0x83847683: 2858 (void) snprintf(buf, sizeof (buf), 2859 "Sigmatel HD codec: STAC9221D"); 2860 break; 2861 case 0x83847610: 2862 (void) snprintf(buf, sizeof (buf), 2863 "Sigmatel HD codec: STAC9230XN"); 2864 break; 2865 case 0x83847611: 2866 (void) snprintf(buf, sizeof (buf), 2867 "Sigmatel HD codec: STAC9230DN"); 2868 break; 2869 case 0x83847612: 2870 (void) snprintf(buf, sizeof (buf), 2871 "Sigmatel HD codec: STAC9230XT"); 2872 break; 2873 case 0x83847613: 2874 (void) snprintf(buf, sizeof (buf), 2875 "Sigmatel HD codec: STAC9230DT"); 2876 break; 2877 case 0x83847614: 2878 (void) snprintf(buf, sizeof (buf), 2879 "Sigmatel HD codec: STAC9229X"); 2880 break; 2881 case 0x83847615: 2882 (void) snprintf(buf, sizeof (buf), 2883 "Sigmatel HD codec: STAC9229D"); 2884 break; 2885 case 0x83847616: 2886 (void) snprintf(buf, sizeof (buf), 2887 "Sigmatel HD codec: STAC9228X"); 2888 break; 2889 case 0x83847617: 2890 (void) snprintf(buf, sizeof (buf), 2891 "Sigmatel HD codec: STAC9228D"); 2892 break; 2893 case 0x83847618: 2894 (void) snprintf(buf, sizeof (buf), 2895 "Sigmatel HD codec: STAC9227X"); 2896 break; 2897 case 0x83847619: 2898 (void) snprintf(buf, sizeof (buf), 2899 "Sigmatel HD codec: STAC9227D"); 2900 break; 2901 case 0x838476a4: 2902 (void) snprintf(buf, sizeof (buf), 2903 "Sigmatel HD codec: STAC9255"); 2904 break; 2905 case 0x838476a5: 2906 (void) snprintf(buf, sizeof (buf), 2907 "Sigmatel HD codec: STAC9255D"); 2908 break; 2909 case 0x838476a6: 2910 (void) snprintf(buf, sizeof (buf), 2911 "Sigmatel HD codec: STAC9254"); 2912 break; 2913 case 0x838476a7: 2914 (void) snprintf(buf, sizeof (buf), 2915 "Sigmatel HD codec: STAC9254D"); 2916 break; 2917 case 0x83847620: 2918 (void) snprintf(buf, sizeof (buf), 2919 "Sigmatel HD codec: STAC9274"); 2920 break; 2921 case 0x83847621: 2922 (void) snprintf(buf, sizeof (buf), 2923 "Sigmatel HD codec: STAC9274D"); 2924 break; 2925 case 0x83847622: 2926 (void) snprintf(buf, sizeof (buf), 2927 "Sigmatel HD codec: STAC9273X"); 2928 break; 2929 case 0x83847623: 2930 (void) snprintf(buf, sizeof (buf), 2931 "Sigmatel HD codec: STAC9273D"); 2932 break; 2933 case 0x83847624: 2934 (void) snprintf(buf, sizeof (buf), 2935 "Sigmatel HD codec: STAC9272X"); 2936 break; 2937 case 0x83847625: 2938 (void) snprintf(buf, sizeof (buf), 2939 "Sigmatel HD codec: STAC9272D"); 2940 break; 2941 case 0x83847626: 2942 (void) snprintf(buf, sizeof (buf), 2943 "Sigmatel HD codec: STAC9271X"); 2944 break; 2945 case 0x83847627: 2946 (void) snprintf(buf, sizeof (buf), 2947 "Sigmatel HD codec: STAC9271D"); 2948 break; 2949 case 0x83847628: 2950 (void) snprintf(buf, sizeof (buf), 2951 "Sigmatel HD codec: STAC9274X5NH"); 2952 break; 2953 case 0x83847629: 2954 (void) snprintf(buf, sizeof (buf), 2955 "Sigmatel HD codec: STAC9274D5NH"); 2956 break; 2957 case 0x83847662: 2958 (void) snprintf(buf, sizeof (buf), 2959 "Sigmatel HD codec: STAC9872AK"); 2960 break; 2961 case 0x83847664: 2962 (void) snprintf(buf, sizeof (buf), 2963 "Sigmatel HD codec: STAC9872K"); 2964 break; 2965 default: 2966 (void) snprintf(buf, sizeof (buf), 2967 "Unkown HD codec"); 2968 break; 2969 2970 } 2971 audio_dev_add_info(codec->soft_statep->adev, buf); 2972 } 2973 /* 2974 * audiohd_create_codec() 2975 * 2976 * Description: 2977 * Searching for supported CODEC. If find, allocate memory 2978 * to hold codec structure. 2979 */ 2980 static int 2981 audiohd_create_codec(audiohd_state_t *statep) 2982 { 2983 hda_codec_t *codec; 2984 uint32_t mask, type; 2985 uint32_t nums; 2986 uint32_t i, j; 2987 wid_t wid; 2988 2989 mask = statep->hda_codec_mask; 2990 ASSERT(mask != 0); 2991 2992 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 2993 if ((mask & (1 << i)) == 0) 2994 continue; 2995 codec = (hda_codec_t *)kmem_zalloc( 2996 sizeof (hda_codec_t), KM_SLEEP); 2997 codec->index = i; 2998 codec->vid = audioha_codec_verb_get(statep, i, 2999 AUDIOHDC_NODE_ROOT, AUDIOHDC_VERB_GET_PARAM, 3000 AUDIOHDC_PAR_VENDOR_ID); 3001 codec->revid = 3002 audioha_codec_verb_get(statep, i, 3003 AUDIOHDC_NODE_ROOT, AUDIOHDC_VERB_GET_PARAM, 3004 AUDIOHDC_PAR_REV_ID); 3005 3006 nums = audioha_codec_verb_get(statep, 3007 i, AUDIOHDC_NODE_ROOT, 3008 AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_NODE_COUNT); 3009 if (nums == (uint32_t)(-1)) { 3010 kmem_free(codec, sizeof (hda_codec_t)); 3011 continue; 3012 } 3013 wid = (nums >> AUDIOHD_CODEC_STR_OFF) & AUDIOHD_CODEC_STR_MASK; 3014 nums = nums & AUDIOHD_CODEC_NUM_MASK; 3015 3016 /* 3017 * Assume that each codec has just one audio function group 3018 */ 3019 for (j = 0; j < nums; j++, wid++) { 3020 type = audioha_codec_verb_get(statep, i, wid, 3021 AUDIOHDC_VERB_GET_PARAM, 3022 AUDIOHDC_PAR_FUNCTION_TYPE); 3023 if ((type & AUDIOHD_CODEC_TYPE_MASK) == 3024 AUDIOHDC_AUDIO_FUNC_GROUP) { 3025 codec->wid_afg = wid; 3026 break; 3027 } 3028 } 3029 3030 if (codec->wid_afg == 0) { 3031 kmem_free(codec, sizeof (hda_codec_t)); 3032 continue; 3033 } 3034 3035 ASSERT(codec->wid_afg == wid); 3036 3037 /* work around for Sony VAIO laptop with specific codec */ 3038 if ((codec->vid != AUDIOHD_CODECID_SONY1) && 3039 (codec->vid != AUDIOHD_CODECID_SONY2)) { 3040 /* 3041 * GPIO controls which are laptop specific workarounds 3042 * and might be changed. Some laptops use GPIO, 3043 * so we need to enable and set the GPIO correctly. 3044 */ 3045 (void) audioha_codec_verb_get(statep, i, wid, 3046 AUDIOHDC_VERB_SET_GPIO_MASK, AUDIOHDC_GPIO_ENABLE); 3047 (void) audioha_codec_verb_get(statep, i, wid, 3048 AUDIOHDC_VERB_SET_GPIO_DIREC, AUDIOHDC_GPIO_DIRECT); 3049 (void) audioha_codec_verb_get(statep, i, wid, 3050 AUDIOHDC_VERB_SET_GPIO_STCK, 3051 AUDIOHDC_GPIO_DATA_CTRL); 3052 (void) audioha_codec_verb_get(statep, i, wid, 3053 AUDIOHDC_VERB_SET_GPIO_DATA, 3054 AUDIOHDC_GPIO_STCK_CTRL); 3055 } 3056 3057 /* power-up audio function group */ 3058 (void) audioha_codec_verb_get(statep, i, wid, 3059 AUDIOHDC_VERB_SET_POWER_STATE, 0); 3060 3061 /* subsystem id is attached to funtion group */ 3062 codec->outamp_cap = audioha_codec_verb_get(statep, i, wid, 3063 AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_OUTAMP_CAP); 3064 codec->inamp_cap = audioha_codec_verb_get(statep, i, wid, 3065 AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_INAMP_CAP); 3066 codec->stream_format = audioha_codec_verb_get(statep, i, wid, 3067 AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_STREAM); 3068 codec->pcm_format = audioha_codec_verb_get(statep, i, wid, 3069 AUDIOHDC_VERB_GET_PARAM, AUDIOHDC_PAR_PCM); 3070 3071 nums = audioha_codec_verb_get(statep, i, wid, 3072 AUDIOHDC_VERB_GET_PARAM, 3073 AUDIOHDC_PAR_NODE_COUNT); 3074 wid = (nums >> AUDIOHD_CODEC_STR_OFF) & AUDIOHD_CODEC_STR_MASK; 3075 nums = nums & AUDIOHD_CODEC_NUM_MASK; 3076 codec->first_wid = wid; 3077 codec->last_wid = wid + nums; 3078 codec->nnodes = nums; 3079 3080 /* 3081 * We output the codec information to syslog 3082 */ 3083 statep->codec[i] = codec; 3084 codec->soft_statep = statep; 3085 audiohd_set_codec_info(codec); 3086 (void) audiohd_create_widgets(codec); 3087 } 3088 3089 return (AUDIO_SUCCESS); 3090 3091 } /* audiohd_create_codec() */ 3092 3093 /* 3094 * audiohd_destroy_codec() 3095 * 3096 * Description: 3097 * destroy codec structure, and release its memory 3098 */ 3099 static void 3100 audiohd_destroy_codec(audiohd_state_t *statep) 3101 { 3102 int i; 3103 audiohd_pin_t *pin, *npin; 3104 3105 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 3106 if (statep->codec[i]) { 3107 audiohd_destroy_widgets(statep->codec[i]); 3108 /* 3109 * free pins 3110 */ 3111 pin = statep->codec[i]->first_pin; 3112 while (pin) { 3113 npin = pin; 3114 pin = pin->next; 3115 kmem_free(npin, sizeof (audiohd_pin_t)); 3116 } 3117 3118 kmem_free(statep->codec[i], sizeof (hda_codec_t)); 3119 statep->codec[i] = NULL; 3120 } 3121 } 3122 } /* audiohd_destroy_codec() */ 3123 3124 /* 3125 * audiohd_find_dac() 3126 * Description: 3127 * Find a dac for a output path. Then the play data can be sent to the out 3128 * put pin through the output path. 3129 * 3130 * Arguments: 3131 * hda_codec_t *codec where the dac widget exists 3132 * wid_t wid the no. of a widget 3133 * int mixer whether the path need mixer or not 3134 * int *mixernum the total of mixer in the output path 3135 * int exclusive an exclusive path or share path 3136 * int depth the depth of search 3137 * 3138 * Return: 3139 * 1) wid of the first shared widget in the path from 3140 * pin to DAC if exclusive is 0; 3141 * 2) wid of DAC widget; 3142 * 3) 0 if no path 3143 */ 3144 static wid_t 3145 audiohd_find_dac(hda_codec_t *codec, wid_t wid, 3146 int mixer, int *mixernum, 3147 int exclusive, int depth) 3148 { 3149 audiohd_widget_t *widget = codec->widget[wid]; 3150 wid_t wdac = (uint32_t)(AUDIO_FAILURE); 3151 wid_t retval; 3152 3153 if (depth > AUDIOHD_MAX_DEPTH) 3154 return (uint32_t)(AUDIO_FAILURE); 3155 3156 if (widget == NULL) 3157 return (uint32_t)(AUDIO_FAILURE); 3158 3159 /* 3160 * If exclusive is true, we try to find a path which doesn't 3161 * share any widget with other paths. 3162 */ 3163 if (exclusive) { 3164 if (widget->path_flags & AUDIOHD_PATH_DAC) 3165 return (uint32_t)(AUDIO_FAILURE); 3166 } else { 3167 if (widget->path_flags & AUDIOHD_PATH_DAC) 3168 return (wid); 3169 } 3170 3171 switch (widget->type) { 3172 case WTYPE_AUDIO_OUT: 3173 /* We need mixer widget, but the the mixer num is 0, failed */ 3174 if (mixer && !*mixernum) 3175 return (uint32_t)(AUDIO_FAILURE); 3176 widget->path_flags |= AUDIOHD_PATH_DAC; 3177 widget->out_weight++; 3178 wdac = widget->wid_wid; 3179 break; 3180 3181 case WTYPE_AUDIO_MIX: 3182 case WTYPE_AUDIO_SEL: 3183 if (widget->type == WTYPE_AUDIO_MIX) 3184 (*mixernum)++; 3185 for (int i = 0; i < widget->nconns; i++) { 3186 retval = audiohd_find_dac(codec, 3187 widget->avail_conn[i], 3188 mixer, mixernum, 3189 exclusive, depth + 1); 3190 if (retval != (uint32_t)AUDIO_FAILURE) { 3191 if (widget->selconn == AUDIOHD_NULL_CONN) { 3192 widget->selconn = i; 3193 wdac = retval; 3194 } 3195 widget->path_flags |= AUDIOHD_PATH_DAC; 3196 widget->out_weight++; 3197 3198 /* return when found a path */ 3199 return (wdac); 3200 } 3201 } 3202 default: 3203 break; 3204 } 3205 3206 return (wdac); 3207 } /* audiohd_find_dac() */ 3208 3209 /* 3210 * audiohd_do_build_output_path() 3211 * 3212 * Description: 3213 * Search an output path for each pin in the codec. 3214 * Arguments: 3215 * hda_codec_t *codec where the output path exists 3216 * int mixer wheter the path needs mixer widget 3217 * int *mnum total of mixer widget in the path 3218 * int exclusive an exclusive path or shared path 3219 * int depth search depth 3220 */ 3221 static void 3222 audiohd_do_build_output_path(hda_codec_t *codec, int mixer, int *mnum, 3223 int exclusive, int depth) 3224 { 3225 audiohd_pin_t *pin; 3226 audiohd_widget_t *widget, *wdac; 3227 audiohd_path_t *path; 3228 wid_t wid; 3229 audiohd_state_t *statep; 3230 int i; 3231 3232 statep = codec->soft_statep; 3233 3234 for (pin = codec->first_pin; pin; pin = pin->next) { 3235 if ((pin->cap & AUDIOHD_PIN_CAP_MASK) == 0) 3236 continue; 3237 if ((pin->config & AUDIOHD_PIN_CONF_MASK) == 3238 AUDIOHD_PIN_NO_CONN) 3239 continue; 3240 if ((pin->device != DTYPE_LINEOUT) && 3241 (pin->device != DTYPE_SPEAKER) && 3242 (pin->device != DTYPE_SPDIF_OUT) && 3243 (pin->device != DTYPE_HP_OUT)) 3244 continue; 3245 if (pin->finish) 3246 continue; 3247 widget = codec->widget[pin->wid]; 3248 3249 widget->inamp_cap = 0; 3250 for (i = 0; i < widget->nconns; i++) { 3251 /* 3252 * If a dac found, the return value is the wid of the 3253 * widget on the path, or the return value is 3254 * AUDIO_FAILURE 3255 */ 3256 wid = audiohd_find_dac(codec, 3257 widget->avail_conn[i], mixer, mnum, exclusive, 3258 depth); 3259 /* 3260 * A dac was not found 3261 */ 3262 if (wid == (wid_t)AUDIO_FAILURE) 3263 continue; 3264 if (pin->device != DTYPE_SPEAKER) 3265 statep->chann[pin->assoc] += 2; 3266 path = (audiohd_path_t *) 3267 kmem_zalloc(sizeof (audiohd_path_t), 3268 KM_SLEEP); 3269 path->adda_wid = wid; 3270 path->pin_wid[0] = widget->wid_wid; 3271 path->pin_nums = 1; 3272 path->path_type = PLAY; 3273 path->codec = codec; 3274 path->statep = statep; 3275 wdac = codec->widget[wid]; 3276 wdac->priv = path; 3277 pin->adc_dac_wid = wid; 3278 pin->finish = 1; 3279 widget->path_flags |= AUDIOHD_PATH_DAC; 3280 widget->out_weight++; 3281 widget->selconn = i; 3282 statep->path[statep->pathnum++] = path; 3283 break; 3284 } 3285 } 3286 3287 } /* audiohd_do_build_output_path() */ 3288 3289 /* 3290 * audiohd_build_output_path() 3291 * 3292 * Description: 3293 * Build the output path in the codec for every pin. 3294 * First we try to search output path with mixer widget exclusively 3295 * Then we try to search shared output path with mixer widget. 3296 * Then we try to search output path without mixer widget exclusively. 3297 * At last we try to search shared ouput path for the remained pins 3298 */ 3299 static void 3300 audiohd_build_output_path(hda_codec_t *codec) 3301 { 3302 int mnum = 0; 3303 uint8_t mixer_allow = 1; 3304 3305 /* work around for hp mini 1000 laptop */ 3306 if (codec->vid == AUDIOHD_CODECID_HP) 3307 mixer_allow = 0; 3308 /* search an exclusive mixer widget path. This is preferred */ 3309 audiohd_do_build_output_path(codec, mixer_allow, &mnum, 1, 0); 3310 3311 /* search a shared mixer widget path for the remained pins */ 3312 audiohd_do_build_output_path(codec, mixer_allow, &mnum, 0, 0); 3313 3314 /* search an exclusive widget path without mixer for the remained pin */ 3315 audiohd_do_build_output_path(codec, 0, &mnum, 1, 0); 3316 3317 /* search a shared widget path without mixer for the remained pin */ 3318 audiohd_do_build_output_path(codec, 0, &mnum, 0, 0); 3319 3320 } /* audiohd_build_output_path */ 3321 3322 /* 3323 * audiohd_build_output_amp 3324 * 3325 * Description: 3326 * Find the gain control and mute control widget 3327 */ 3328 static void 3329 audiohd_build_output_amp(hda_codec_t *codec) 3330 { 3331 audiohd_path_t *path; 3332 audiohd_widget_t *w, *widget, *wpin, *wdac; 3333 audiohd_pin_t *pin; 3334 wid_t wid; 3335 int weight; 3336 int i, j; 3337 uint32_t gain; 3338 3339 for (i = 0; i < codec->soft_statep->pathnum; i++) { 3340 path = codec->soft_statep->path[i]; 3341 if (path == NULL || path->path_type == RECORD || 3342 path->codec != codec) 3343 continue; 3344 for (j = 0; j < path->pin_nums; j++) { 3345 wid = path->pin_wid[j]; 3346 wpin = codec->widget[wid]; 3347 pin = (audiohd_pin_t *)wpin->priv; 3348 weight = wpin->out_weight; 3349 3350 /* 3351 * search a node which can mute this pin while 3352 * the mute functionality doesn't effect other 3353 * pins. 3354 */ 3355 widget = wpin; 3356 while (widget) { 3357 if (widget->outamp_cap & 3358 AUDIOHDC_AMP_CAP_MUTE_CAP) { 3359 pin->mute_wid = widget->wid_wid; 3360 pin->mute_dir = AUDIOHDC_AMP_SET_OUTPUT; 3361 break; 3362 } 3363 if (widget->inamp_cap & 3364 AUDIOHDC_AMP_CAP_MUTE_CAP) { 3365 pin->mute_wid = widget->wid_wid; 3366 pin->mute_dir = AUDIOHDC_AMP_SET_INPUT; 3367 break; 3368 } 3369 if (widget->selconn == AUDIOHD_NULL_CONN) 3370 break; 3371 wid = widget->avail_conn[widget->selconn]; 3372 widget = codec->widget[wid]; 3373 if (widget && widget->out_weight != weight) 3374 break; 3375 } 3376 3377 /* 3378 * We select the wid which has maxium gain range in 3379 * the output path. Meanwhile, the gain controlling 3380 * of this node doesn't effect other pins if this 3381 * output stream has multiple pins. 3382 */ 3383 gain = 0; 3384 widget = wpin; 3385 while (widget) { 3386 gain = (widget->outamp_cap & 3387 AUDIOHDC_AMP_CAP_STEP_NUMS); 3388 if (gain && gain > pin->gain_bits) { 3389 pin->gain_dir = AUDIOHDC_AMP_SET_OUTPUT; 3390 pin->gain_bits = gain; 3391 pin->gain_wid = widget->wid_wid; 3392 } 3393 gain = widget->inamp_cap & 3394 AUDIOHDC_AMP_CAP_STEP_NUMS; 3395 if (gain && gain > pin->gain_bits) { 3396 pin->gain_dir = AUDIOHDC_AMP_SET_INPUT; 3397 pin->gain_bits = gain; 3398 pin->gain_wid = widget->wid_wid; 3399 } 3400 if (widget->selconn == AUDIOHD_NULL_CONN) 3401 break; 3402 wid = widget->avail_conn[widget->selconn]; 3403 widget = codec->widget[wid]; 3404 if (widget && widget->out_weight != weight) 3405 break; 3406 } 3407 pin->gain_bits >>= AUDIOHD_GAIN_OFF; 3408 } 3409 3410 /* 3411 * if this stream has multiple pins, we try to find 3412 * a mute & gain-controlling nodes which can effect 3413 * all output pins of this stream to be used for the 3414 * whole stream 3415 */ 3416 if (path->pin_nums == 1) { 3417 path->mute_wid = pin->mute_wid; 3418 path->mute_dir = pin->mute_dir; 3419 path->gain_wid = pin->gain_wid; 3420 path->gain_dir = pin->gain_dir; 3421 path->gain_bits = pin->gain_bits; 3422 } else { 3423 wdac = codec->widget[path->adda_wid]; 3424 weight = wdac->out_weight; 3425 wid = path->pin_wid[0]; 3426 w = codec->widget[wid]; 3427 while (w && w->out_weight != weight) { 3428 wid = w->avail_conn[w->selconn]; 3429 w = codec->widget[wid]; 3430 } 3431 3432 /* find mute controlling node for this stream */ 3433 widget = w; 3434 while (widget) { 3435 if (widget->outamp_cap & 3436 AUDIOHDC_AMP_CAP_MUTE_CAP) { 3437 path->mute_wid = widget->wid_wid; 3438 path->mute_dir = 3439 AUDIOHDC_AMP_SET_OUTPUT; 3440 break; 3441 } 3442 if (widget->inamp_cap & 3443 AUDIOHDC_AMP_CAP_MUTE_CAP) { 3444 path->mute_wid = widget->wid_wid; 3445 path->mute_dir = 3446 AUDIOHDC_AMP_SET_INPUT; 3447 break; 3448 } 3449 if (widget->selconn == AUDIOHD_NULL_CONN) 3450 break; 3451 wid = widget->avail_conn[widget->selconn]; 3452 widget = codec->widget[wid]; 3453 } 3454 3455 /* find volume controlling node for this stream */ 3456 gain = 0; 3457 widget = w; 3458 while (widget) { 3459 gain = (widget->outamp_cap & 3460 AUDIOHDC_AMP_CAP_STEP_NUMS); 3461 if (gain && gain > pin->gain_bits) { 3462 path->gain_dir = 3463 AUDIOHDC_AMP_SET_OUTPUT; 3464 path->gain_bits = gain; 3465 path->gain_wid = widget->wid_wid; 3466 } 3467 gain = widget->inamp_cap & 3468 AUDIOHDC_AMP_CAP_STEP_NUMS; 3469 if (gain && (gain > pin->gain_bits) && 3470 (widget->type != WTYPE_AUDIO_MIX)) { 3471 path->gain_dir = 3472 AUDIOHDC_AMP_SET_INPUT; 3473 path->gain_bits = gain; 3474 path->gain_wid = widget->wid_wid; 3475 } 3476 if (widget->selconn == AUDIOHD_NULL_CONN) 3477 break; 3478 wid = widget->avail_conn[widget->selconn]; 3479 widget = codec->widget[wid]; 3480 } 3481 path->gain_bits >>= AUDIOHD_GAIN_OFF; 3482 } 3483 3484 } 3485 3486 } /* audiohd_build_output_amp */ 3487 3488 /* 3489 * audiohd_finish_output_path() 3490 * 3491 * Description: 3492 * Enable the widgets on the output path 3493 */ 3494 static void 3495 audiohd_finish_output_path(hda_codec_t *codec) 3496 { 3497 audiohd_state_t *statep = codec->soft_statep; 3498 audiohd_path_t *path; 3499 audiohd_widget_t *widget; 3500 audiohd_pin_t *pin; 3501 uint_t caddr = codec->index; 3502 wid_t wid; 3503 int i, j; 3504 3505 for (i = 0; i < codec->soft_statep->pathnum; i++) { 3506 path = codec->soft_statep->path[i]; 3507 if (!path || path->path_type != PLAY || path->codec != codec) 3508 continue; 3509 for (j = 0; j < path->pin_nums; j++) { 3510 wid = path->pin_wid[j]; 3511 widget = codec->widget[wid]; 3512 pin = (audiohd_pin_t *)widget->priv; 3513 { 3514 uint32_t lTmp; 3515 3516 lTmp = audioha_codec_verb_get(statep, caddr, wid, 3517 AUDIOHDC_VERB_GET_PIN_CTRL, 0); 3518 (void) audioha_codec_verb_get(statep, caddr, wid, 3519 AUDIOHDC_VERB_SET_PIN_CTRL, (lTmp | 3520 pin->vrefvalue | 3521 AUDIOHDC_PIN_CONTROL_OUT_ENABLE | 3522 AUDIOHDC_PIN_CONTROL_HP_ENABLE) & 3523 ~ AUDIOHDC_PIN_CONTROL_IN_ENABLE); 3524 } 3525 /* If this pin has external amplifier, enable it */ 3526 if (pin->cap & AUDIOHD_EXT_AMP_MASK) 3527 (void) audioha_codec_verb_get(statep, caddr, 3528 wid, AUDIOHDC_VERB_SET_EAPD, 3529 AUDIOHD_EXT_AMP_ENABLE); 3530 3531 if (widget->outamp_cap) { 3532 (void) audioha_codec_4bit_verb_get(statep, 3533 caddr, wid, AUDIOHDC_VERB_SET_AMP_MUTE, 3534 AUDIOHDC_AMP_SET_LR_OUTPUT | 3535 AUDIOHDC_GAIN_MAX); 3536 } 3537 3538 (void) audioha_codec_verb_get(statep, caddr, wid, 3539 AUDIOHDC_VERB_SET_CONN_SEL, widget->selconn); 3540 3541 wid = widget->avail_conn[widget->selconn]; 3542 widget = codec->widget[wid]; 3543 3544 while (widget) { 3545 /* 3546 * Set all amplifiers in this path to 3547 * the maximum 3548 * volume and unmute them. 3549 */ 3550 if (widget->outamp_cap) { 3551 (void) audioha_codec_4bit_verb_get( 3552 statep, 3553 caddr, 3554 wid, AUDIOHDC_VERB_SET_AMP_MUTE, 3555 AUDIOHDC_AMP_SET_LR_OUTPUT | 3556 AUDIOHDC_GAIN_MAX); 3557 } 3558 if (widget->inamp_cap) { 3559 (void) audioha_codec_4bit_verb_get( 3560 statep, 3561 caddr, 3562 wid, AUDIOHDC_VERB_SET_AMP_MUTE, 3563 AUDIOHDC_AMP_SET_LR_INPUT | 3564 AUDIOHDC_GAIN_MAX | 3565 (widget->selconn << 3566 AUDIOHDC_AMP_SET_INDEX_OFFSET)); 3567 } 3568 3569 if (widget->selconn == AUDIOHD_NULL_CONN) 3570 break; 3571 /* 3572 * Accoding to HD spec, mixer doesn't support 3573 * "select connection" 3574 */ 3575 if ((widget->type != WTYPE_AUDIO_MIX) && 3576 (widget->nconns > 1)) 3577 (void) audioha_codec_verb_get(statep, 3578 caddr, 3579 wid, 3580 AUDIOHDC_VERB_SET_CONN_SEL, 3581 widget->selconn); 3582 3583 wid = widget->avail_conn[widget->selconn]; 3584 widget = codec->widget[wid]; 3585 } 3586 } 3587 } 3588 } /* audiohd_finish_output_path() */ 3589 3590 /* 3591 * audiohd_find_input_pins() 3592 * 3593 * Description: 3594 * Here we consider a mixer/selector with multi-input as a real sum 3595 * widget. Only the first real mixer/selector widget is permitted in 3596 * an input path(recording path). If there are more mixers/selectors 3597 * execept the first one, only the first input/connection of those 3598 * widgets will be used by our driver, that means, we ignore other 3599 * inputs of those mixers/selectors. 3600 */ 3601 static int 3602 audiohd_find_input_pins(hda_codec_t *codec, wid_t wid, int allowmixer, 3603 int depth, audiohd_path_t *path) 3604 { 3605 audiohd_widget_t *widget = codec->widget[wid]; 3606 audiohd_pin_t *pin; 3607 audiohd_state_t *statep = codec->soft_statep; 3608 uint_t caddr = codec->index; 3609 int retval = -1; 3610 int num, i; 3611 uint32_t pinctrl; 3612 3613 if (depth > AUDIOHD_MAX_DEPTH) 3614 return (uint32_t)(AUDIO_FAILURE); 3615 if (widget == NULL) 3616 return (uint32_t)(AUDIO_FAILURE); 3617 3618 /* we don't share widgets */ 3619 if (widget->path_flags & AUDIOHD_PATH_ADC || 3620 widget->path_flags & AUDIOHD_PATH_DAC) 3621 return (uint32_t)(AUDIO_FAILURE); 3622 3623 switch (widget->type) { 3624 case WTYPE_PIN: 3625 pin = (audiohd_pin_t *)widget->priv; 3626 if (pin->no_phys_conn) 3627 return (uint32_t)(AUDIO_FAILURE); 3628 /* enable the pins' input capability */ 3629 pinctrl = audioha_codec_verb_get(statep, caddr, wid, 3630 AUDIOHDC_VERB_GET_PIN_CTRL, 0); 3631 (void) audioha_codec_verb_get(statep, caddr, wid, 3632 AUDIOHDC_VERB_SET_PIN_CTRL, 3633 pinctrl | AUDIOHD_PIN_IN_ENABLE); 3634 if (pin->cap & AUDIOHD_EXT_AMP_MASK) { 3635 (void) audioha_codec_verb_get(statep, caddr, 3636 wid, AUDIOHDC_VERB_SET_EAPD, 3637 AUDIOHD_EXT_AMP_ENABLE); 3638 } 3639 switch (pin->device) { 3640 case DTYPE_CD: 3641 case DTYPE_LINE_IN: 3642 case DTYPE_MIC_IN: 3643 case DTYPE_AUX: 3644 widget->path_flags |= AUDIOHD_PATH_ADC; 3645 widget->in_weight++; 3646 path->pin_wid[path->pin_nums++] = wid; 3647 pin->adc_dac_wid = path->adda_wid; 3648 return (AUDIO_SUCCESS); 3649 } 3650 break; 3651 case WTYPE_AUDIO_MIX: 3652 case WTYPE_AUDIO_SEL: 3653 /* 3654 * If the sum widget has only one input, we don't 3655 * consider it as a real sum widget. 3656 */ 3657 if (widget->nconns == 1) { 3658 widget->selconn = 0; 3659 retval = audiohd_find_input_pins(codec, 3660 widget->avail_conn[0], 3661 allowmixer, depth + 1, path); 3662 if (retval != AUDIO_FAILURE) { 3663 widget->path_flags |= AUDIOHD_PATH_ADC; 3664 widget->in_weight++; 3665 } 3666 break; 3667 } 3668 3669 if (allowmixer) { 3670 /* 3671 * This is a real sum widget, we will reject 3672 * other real sum widget when we find more in 3673 * the following path-searching. 3674 */ 3675 for (int i = 0; i < widget->nconns; i++) { 3676 retval = audiohd_find_input_pins(codec, 3677 widget->avail_conn[i], 0, depth + 1, 3678 path); 3679 if (retval != AUDIO_FAILURE) { 3680 widget->in_weight++; 3681 num = path->pin_nums - 1; 3682 path->sum_selconn[num] = i; 3683 path->sum_wid = wid; 3684 widget->path_flags |= 3685 AUDIOHD_PATH_ADC; 3686 if (widget->selconn == 3687 AUDIOHD_NULL_CONN) { 3688 widget->selconn = i; 3689 } 3690 } 3691 } 3692 3693 /* return SUCCESS if we found at least one input path */ 3694 if (path->pin_nums > 0) 3695 retval = AUDIO_SUCCESS; 3696 } else { 3697 /* 3698 * We had already found a real sum before this one since 3699 * allowmixer is 0. 3700 */ 3701 for (i = 0; i < widget->nconns; i++) { 3702 retval = audiohd_find_input_pins(codec, 3703 widget->avail_conn[i], 0, depth + 1, 3704 path); 3705 if (retval != AUDIO_FAILURE) { 3706 widget->selconn = i; 3707 widget->path_flags |= AUDIOHD_PATH_ADC; 3708 widget->in_weight++; 3709 break; 3710 } 3711 } 3712 } 3713 break; 3714 default: 3715 break; 3716 } 3717 3718 return (retval); 3719 } /* audiohd_find_input_pins */ 3720 3721 /* 3722 * audiohd_build_input_path() 3723 * 3724 * Description: 3725 * Find input path for the codec 3726 */ 3727 static void 3728 audiohd_build_input_path(hda_codec_t *codec) 3729 { 3730 audiohd_widget_t *widget; 3731 audiohd_path_t *path = NULL; 3732 wid_t wid; 3733 int i; 3734 int retval; 3735 uint8_t rtag = 0; 3736 audiohd_state_t *statep = codec->soft_statep; 3737 3738 for (wid = codec->first_wid; wid <= codec->last_wid; wid++) { 3739 3740 widget = codec->widget[wid]; 3741 3742 /* check if it is an ADC widget */ 3743 if (!widget || widget->type != WTYPE_AUDIO_IN) 3744 continue; 3745 3746 if (path == NULL) 3747 path = kmem_zalloc(sizeof (audiohd_path_t), 3748 KM_SLEEP); 3749 else 3750 bzero(path, sizeof (audiohd_port_t)); 3751 3752 path->adda_wid = wid; 3753 3754 /* 3755 * Is there any ADC widget which has more than one input ?? 3756 * I don't believe. Anyway, we carefully deal with this. But 3757 * if hardware vendors embed a selector in a ADC, we just use 3758 * the first available input, which has connection to input pin 3759 * widget. Because selector cannot perform mixer functionality, 3760 * and we just permit one selector or mixer in a recording path, 3761 * if we use the selector embedded in ADC,we cannot use possible 3762 * mixer during path searching. 3763 */ 3764 for (i = 0; i < widget->nconns; i++) { 3765 retval = audiohd_find_input_pins(codec, 3766 widget->avail_conn[i], 1, 0, path); 3767 if (retval == AUDIO_SUCCESS) { 3768 path->codec = codec; 3769 path->statep = statep; 3770 path->path_type = RECORD; 3771 path->tag = ++rtag; 3772 codec->nistream++; 3773 statep->path[statep->pathnum++] = path; 3774 widget->selconn = i; 3775 widget->priv = path; 3776 path = NULL; 3777 break; 3778 } 3779 } 3780 } 3781 if (path) 3782 kmem_free(path, sizeof (audiohd_path_t)); 3783 } /* audiohd_build_input_path */ 3784 3785 /* 3786 * audiohd_build_input_amp() 3787 * 3788 * Description: 3789 * Find gain and mute control widgets on the input path 3790 */ 3791 static void 3792 audiohd_build_input_amp(hda_codec_t *codec) 3793 { 3794 audiohd_path_t *path; 3795 audiohd_widget_t *wsum, *wadc, *w; 3796 audiohd_pin_t *pin; 3797 uint_t gain; 3798 wid_t wid; 3799 int i, j; 3800 int weight; 3801 3802 for (i = 0; i < codec->soft_statep->pathnum; i++) { 3803 path = codec->soft_statep->path[i]; 3804 if (path == NULL || path->path_type == PLAY || 3805 path->codec != codec) 3806 continue; 3807 3808 wid = path->adda_wid; 3809 wadc = path->codec->widget[wid]; 3810 weight = wadc->in_weight; 3811 3812 /* 3813 * Search node which has mute functionality for 3814 * the whole input path 3815 */ 3816 w = wadc; 3817 while (w) { 3818 if (w->outamp_cap & AUDIOHDC_AMP_CAP_MUTE_CAP) { 3819 path->mute_wid = w->wid_wid; 3820 path->mute_dir = AUDIOHDC_AMP_SET_OUTPUT; 3821 break; 3822 } 3823 if ((w->inamp_cap & AUDIOHDC_AMP_CAP_MUTE_CAP) && 3824 (w->wid_wid != path->sum_wid)) { 3825 path->mute_wid = w->wid_wid; 3826 path->mute_dir = AUDIOHDC_AMP_SET_INPUT; 3827 break; 3828 } 3829 3830 if (w->selconn == AUDIOHD_NULL_CONN) 3831 break; 3832 wid = w->avail_conn[w->selconn]; 3833 w = path->codec->widget[wid]; 3834 if (w && w->in_weight != weight) 3835 break; 3836 } 3837 3838 /* 3839 * Search a node for amplifier adjusting for the whole 3840 * input path 3841 */ 3842 w = wadc; 3843 gain = 0; 3844 while (w) { 3845 gain = (w->outamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS); 3846 if (gain && gain > path->gain_bits) { 3847 path->gain_dir = AUDIOHDC_AMP_SET_OUTPUT; 3848 path->gain_bits = gain; 3849 path->gain_wid = w->wid_wid; 3850 } 3851 gain = w->inamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS; 3852 if (gain && (gain > path->gain_bits) && 3853 (w->wid_wid != path->sum_wid)) { 3854 path->gain_dir = AUDIOHDC_AMP_SET_INPUT; 3855 path->gain_bits = gain; 3856 path->gain_wid = w->wid_wid; 3857 } 3858 if (w->selconn == AUDIOHD_NULL_CONN) 3859 break; 3860 wid = w->avail_conn[w->selconn]; 3861 w = path->codec->widget[wid]; 3862 } 3863 path->gain_bits >>= AUDIOHD_GAIN_OFF; 3864 3865 /* 3866 * If the input path has one pin only, the mute/amp 3867 * controlling is shared by the whole path and pin 3868 */ 3869 if (path->pin_nums == 1) { 3870 wid = path->pin_wid[0]; 3871 w = path->codec->widget[wid]; 3872 pin = (audiohd_pin_t *)w->priv; 3873 pin->gain_dir = path->gain_dir; 3874 pin->gain_bits = path->gain_bits; 3875 pin->gain_wid = path->gain_wid; 3876 pin->mute_wid = path->mute_wid; 3877 pin->mute_dir = path->mute_dir; 3878 continue; 3879 } 3880 3881 /* 3882 * For multi-pin device, there must be a selector 3883 * or mixer along the input path, and the sum_wid 3884 * is the widget's node id. 3885 */ 3886 wid = path->sum_wid; 3887 wsum = path->codec->widget[wid]; /* sum widget */ 3888 3889 for (j = 0; j < path->pin_nums; j++) { 3890 wid = path->pin_wid[j]; 3891 w = path->codec->widget[wid]; 3892 pin = (audiohd_pin_t *)w->priv; 3893 3894 /* find node for mute */ 3895 if (wsum->inamp_cap & AUDIOHDC_AMP_CAP_MUTE_CAP) { 3896 pin->mute_wid = wsum->wid_wid; 3897 pin->mute_dir = AUDIOHDC_AMP_SET_INPUT; 3898 } else { 3899 wid = wsum->avail_conn[path->sum_selconn[i]]; 3900 w = path->codec->widget[wid]; 3901 while (w) { 3902 if (w->outamp_cap & 3903 AUDIOHDC_AMP_CAP_MUTE_CAP) { 3904 pin->mute_wid = w->wid_wid; 3905 pin->mute_dir = 3906 AUDIOHDC_AMP_SET_OUTPUT; 3907 break; 3908 } 3909 if (w->inamp_cap & 3910 AUDIOHDC_AMP_CAP_MUTE_CAP) { 3911 pin->mute_wid = w->wid_wid; 3912 pin->mute_dir = 3913 AUDIOHDC_AMP_SET_INPUT; 3914 break; 3915 } 3916 3917 if (w->selconn == AUDIOHD_NULL_CONN) 3918 break; 3919 wid = w->avail_conn[w->selconn]; 3920 w = path->codec->widget[wid]; 3921 } 3922 } 3923 3924 /* find node for amp controlling */ 3925 gain = (wsum->inamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS); 3926 wid = wsum->avail_conn[path->sum_selconn[i]]; 3927 w = path->codec->widget[wid]; 3928 while (w) { 3929 gain = (w->outamp_cap & 3930 AUDIOHDC_AMP_CAP_STEP_NUMS); 3931 if (gain && gain > pin->gain_bits) { 3932 pin->gain_dir = AUDIOHDC_AMP_SET_OUTPUT; 3933 pin->gain_bits = gain; 3934 pin->gain_wid = w->wid_wid; 3935 } 3936 gain = w->inamp_cap & 3937 AUDIOHDC_AMP_CAP_STEP_NUMS; 3938 if (gain && (gain > pin->gain_bits)) { 3939 pin->gain_dir = AUDIOHDC_AMP_SET_INPUT; 3940 pin->gain_bits = gain; 3941 pin->gain_wid = w->wid_wid; 3942 } 3943 if (w->selconn == AUDIOHD_NULL_CONN) 3944 break; 3945 wid = w->avail_conn[w->selconn]; 3946 w = path->codec->widget[wid]; 3947 } 3948 pin->gain_bits >>= AUDIOHD_GAIN_OFF; 3949 } 3950 } 3951 } /* audiohd_build_input_amp() */ 3952 3953 /* 3954 * audiohd_finish_input_path() 3955 * 3956 * Description: 3957 * Enable the widgets on the input path 3958 */ 3959 static void 3960 audiohd_finish_input_path(hda_codec_t *codec) 3961 { 3962 audiohd_state_t *statep = codec->soft_statep; 3963 audiohd_path_t *path; 3964 audiohd_widget_t *w, *wsum; 3965 uint_t caddr = codec->index; 3966 wid_t wid; 3967 int i, j; 3968 3969 for (i = 0; i < codec->soft_statep->pathnum; i++) { 3970 path = codec->soft_statep->path[i]; 3971 if (path == NULL || path->path_type == PLAY || 3972 path->codec != codec) 3973 continue; 3974 wid = path->adda_wid; 3975 w = path->codec->widget[wid]; 3976 while (w && (w->wid_wid != path->sum_wid) && 3977 (w->type != WTYPE_PIN)) { 3978 if ((w->type == WTYPE_AUDIO_SEL) && (w->nconns > 1)) 3979 (void) audioha_codec_verb_get(statep, caddr, 3980 w->wid_wid, 3981 AUDIOHDC_VERB_SET_CONN_SEL, w->selconn); 3982 3983 if (w->outamp_cap) { 3984 (void) audioha_codec_4bit_verb_get(statep, 3985 caddr, 3986 w->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE, 3987 AUDIOHDC_AMP_SET_LR_OUTPUT | 3988 AUDIOHDC_GAIN_MAX); 3989 } 3990 3991 if (w->inamp_cap) { 3992 (void) audioha_codec_4bit_verb_get(statep, 3993 caddr, 3994 w->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE, 3995 AUDIOHDC_AMP_SET_LR_INPUT | 3996 AUDIOHDC_GAIN_MAX | 3997 (w->selconn << 3998 AUDIOHDC_AMP_SET_INDEX_OFFSET)); 3999 } 4000 4001 wid = w->avail_conn[w->selconn]; 4002 w = path->codec->widget[wid]; 4003 } 4004 4005 /* 4006 * After exiting from the above loop, the widget pointed 4007 * by w can be a pin widget or select/mixer widget. If it 4008 * is a pin widget, we already finish "select connection" 4009 * operation for the whole path. 4010 */ 4011 if (w && w->type == WTYPE_PIN) 4012 continue; 4013 4014 /* 4015 * deal with multi-pin input devices. 4016 */ 4017 wid = path->sum_wid; 4018 wsum = path->codec->widget[wid]; 4019 if (wsum == NULL) 4020 continue; 4021 if (wsum->outamp_cap) { 4022 (void) audioha_codec_4bit_verb_get(statep, 4023 caddr, 4024 wsum->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE, 4025 AUDIOHDC_AMP_SET_LR_OUTPUT | 4026 AUDIOHDC_GAIN_MAX); 4027 } 4028 4029 for (j = 0; j < path->pin_nums; j++) { 4030 if (wsum->inamp_cap) { 4031 (void) audioha_codec_4bit_verb_get(statep, 4032 caddr, 4033 wsum->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE, 4034 AUDIOHDC_AMP_SET_LR_INPUT | 4035 AUDIOHDC_GAIN_MAX | 4036 (path->sum_selconn[j] << 4037 AUDIOHDC_AMP_SET_INDEX_OFFSET)); 4038 } 4039 if (wsum->type == WTYPE_AUDIO_SEL) { 4040 (void) audioha_codec_verb_get(statep, caddr, 4041 wsum->wid_wid, 4042 AUDIOHDC_VERB_SET_CONN_SEL, 4043 path->sum_selconn[j]); 4044 } 4045 4046 wid = wsum->avail_conn[path->sum_selconn[j]]; 4047 w = path->codec->widget[wid]; 4048 while (w && w->type != WTYPE_PIN) { 4049 if ((w->type != WTYPE_AUDIO_MIX) && 4050 (w->nconns > 1)) 4051 (void) audioha_codec_verb_get(statep, 4052 caddr, w->wid_wid, 4053 AUDIOHDC_VERB_SET_CONN_SEL, 4054 w->selconn); 4055 4056 if (w->outamp_cap) { 4057 (void) audioha_codec_4bit_verb_get( 4058 statep, 4059 caddr, 4060 w->wid_wid, 4061 AUDIOHDC_VERB_SET_AMP_MUTE, 4062 AUDIOHDC_AMP_SET_LR_OUTPUT | 4063 AUDIOHDC_GAIN_MAX); 4064 } 4065 4066 if (w->inamp_cap) { 4067 (void) audioha_codec_4bit_verb_get( 4068 statep, 4069 caddr, 4070 w->wid_wid, 4071 AUDIOHDC_VERB_SET_AMP_MUTE, 4072 AUDIOHDC_AMP_SET_LR_INPUT | 4073 AUDIOHDC_GAIN_MAX | 4074 (w->selconn << 4075 AUDIOHDC_AMP_SET_INDEX_OFFSET)); 4076 } 4077 wid = w->avail_conn[w->selconn]; 4078 w = path->codec->widget[wid]; 4079 } 4080 } 4081 } /* end of istream loop */ 4082 } /* audiohd_finish_input_path */ 4083 4084 /* 4085 * audiohd_find_inpin_for_monitor() 4086 * 4087 * Description: 4088 * Find input pin for monitor path. 4089 * 4090 * Arguments: 4091 * hda_codec_t *codec where the monitor path exists 4092 * audiohd_ostream_t *ostream output ostream 4093 * wid_t id no. of widget being searched 4094 * int mixer share or not 4095 */ 4096 static int 4097 audiohd_find_inpin_for_monitor(hda_codec_t *codec, 4098 audiohd_path_t *path, wid_t id, int mixer) 4099 { 4100 wid_t wid; 4101 audiohd_widget_t *widget; 4102 audiohd_pin_t *pin; 4103 int i, find = 0; 4104 4105 wid = id; 4106 widget = codec->widget[wid]; 4107 if (widget == NULL) 4108 return (uint32_t)(AUDIO_FAILURE); 4109 4110 if (widget->type == WTYPE_PIN) { 4111 pin = (audiohd_pin_t *)widget->priv; 4112 if (pin->no_phys_conn) 4113 return (uint32_t)(AUDIO_FAILURE); 4114 switch (pin->device) { 4115 case DTYPE_SPDIF_IN: 4116 widget->path_flags |= AUDIOHD_PATH_MON; 4117 return (AUDIO_SUCCESS); 4118 case DTYPE_CD: 4119 widget->path_flags |= AUDIOHD_PATH_MON; 4120 return (AUDIO_SUCCESS); 4121 case DTYPE_LINE_IN: 4122 widget->path_flags |= AUDIOHD_PATH_MON; 4123 return (AUDIO_SUCCESS); 4124 case DTYPE_MIC_IN: 4125 widget->path_flags |= AUDIOHD_PATH_MON; 4126 return (AUDIO_SUCCESS); 4127 case DTYPE_AUX: 4128 widget->path_flags |= AUDIOHD_PATH_MON; 4129 return (AUDIO_SUCCESS); 4130 default: 4131 return (uint32_t)(AUDIO_FAILURE); 4132 } 4133 } 4134 /* the widget has been visited and can't be directed to input pin */ 4135 if (widget->path_flags & AUDIOHD_PATH_NOMON) { 4136 return (uint32_t)(AUDIO_FAILURE); 4137 } 4138 /* the widget has been used by the monitor path, and we can share it */ 4139 if (widget->path_flags & AUDIOHD_PATH_MON) { 4140 if (mixer) 4141 return (AUDIO_SUCCESS); 4142 else 4143 return (uint32_t)(AUDIO_FAILURE); 4144 } 4145 switch (widget->type) { 4146 case WTYPE_AUDIO_MIX: 4147 for (i = 0; i < widget->nconns; i++) { 4148 if (widget->selconn == i && widget->path_flags & 4149 AUDIOHD_PATH_DAC) 4150 continue; 4151 if (audiohd_find_inpin_for_monitor(codec, 4152 path, 4153 widget->avail_conn[i], mixer) == 4154 AUDIO_SUCCESS) { 4155 widget->selmon[widget->used++] = i; 4156 widget->path_flags |= AUDIOHD_PATH_MON; 4157 find = 1; 4158 } 4159 } 4160 break; 4161 case WTYPE_AUDIO_SEL: 4162 for (i = 0; i < widget->nconns; i++) { 4163 if (widget->selconn == i && widget->path_flags & 4164 AUDIOHD_PATH_DAC) 4165 continue; 4166 if (audiohd_find_inpin_for_monitor(codec, 4167 path, 4168 widget->avail_conn[i], 4169 mixer) == 4170 AUDIO_SUCCESS) { 4171 widget->selmon[0] = i; 4172 widget->path_flags |= AUDIOHD_PATH_MON; 4173 return (AUDIO_SUCCESS); 4174 } 4175 } 4176 default: 4177 break; 4178 } 4179 if (!find) { 4180 widget->path_flags |= AUDIOHD_PATH_NOMON; 4181 return (uint32_t)(AUDIO_FAILURE); 4182 } 4183 else 4184 return (AUDIO_SUCCESS); 4185 } /* audiohd_find_inpin_for_monitor */ 4186 4187 /* 4188 * audiohd_build_monitor_path() 4189 * 4190 * Description: 4191 * The functionality of mixer is to mix inputs, such as CD-IN, MIC, 4192 * Line-in, etc, with DAC outputs, so as to minitor what is being 4193 * recorded and implement "What you hear is what you get". However, 4194 * this functionality are really hardware-dependent: the inputs 4195 * must be directed to MIXER if they can be directed to ADC as 4196 * recording sources. 4197 */ 4198 static void 4199 audiohd_build_monitor_path(hda_codec_t *codec) 4200 { 4201 audiohd_path_t *path; 4202 audiohd_widget_t *widget; 4203 audiohd_state_t *statep = codec->soft_statep; 4204 wid_t wid; 4205 int i, j, k, l, find; 4206 int mixernum = 0; 4207 4208 for (i = 0; i < statep->pathnum; i++) { 4209 path = statep->path[i]; 4210 if (!path || path->codec != codec ||path->path_type != PLAY) 4211 continue; 4212 for (j = 0; j < path->pin_nums; j++) { 4213 wid = path->pin_wid[j]; 4214 widget = codec->widget[wid]; 4215 l = 0; 4216 while (widget) { 4217 while (widget && 4218 ((widget->type != WTYPE_AUDIO_MIX) || 4219 (widget->nconns < 2))) { 4220 if (widget->selconn == 4221 AUDIOHD_NULL_CONN) 4222 break; 4223 wid = 4224 widget->avail_conn[widget->selconn]; 4225 widget = codec->widget[wid]; 4226 } 4227 4228 /* 4229 * No mixer in this output path, we cannot build 4230 * mixer path for this path, skip it, 4231 * and continue 4232 * for next output path. 4233 */ 4234 if (widget == NULL || widget->selconn == 4235 AUDIOHD_NULL_CONN) { 4236 break; 4237 } 4238 mixernum++; 4239 for (k = 0; k < widget->nconns; k++) { 4240 4241 /* 4242 * this connection must be routined 4243 * to DAC instead of an input pin 4244 * widget, we needn't waste time for 4245 * it 4246 */ 4247 if (widget->selconn == k) 4248 continue; 4249 find = 0; 4250 if (audiohd_find_inpin_for_monitor( 4251 codec, 4252 path, 4253 widget->avail_conn[k], 0) == 4254 AUDIO_SUCCESS) { 4255 path->mon_wid[j][l] = wid; 4256 widget->selmon[widget->used++] = 4257 k; 4258 widget->path_flags |= 4259 AUDIOHD_PATH_MON; 4260 find = 1; 4261 } else if ( 4262 audiohd_find_inpin_for_monitor( 4263 codec, 4264 path, 4265 widget->avail_conn[k], 1) == 4266 AUDIO_SUCCESS) { 4267 path->mon_wid[j][l] = wid; 4268 widget->selmon[widget->used++] = 4269 k; 4270 widget->path_flags |= 4271 AUDIOHD_PATH_MON; 4272 find = 1; 4273 4274 } 4275 4276 } 4277 4278 /* 4279 * we needn't check widget->selconn here 4280 * since this 4281 * widget is a selector or mixer, it cannot 4282 * be NULL connection. 4283 */ 4284 if (!find) { 4285 path->mon_wid[i][l] = 0; 4286 widget->path_flags |= 4287 AUDIOHD_PATH_NOMON; 4288 } 4289 wid = widget->avail_conn[widget->selconn]; 4290 widget = codec->widget[wid]; 4291 l++; 4292 } 4293 path->maxmixer[j] = l; 4294 } 4295 4296 } 4297 if (mixernum == 0) 4298 statep->monitor_unsupported = B_TRUE; 4299 else 4300 statep->monitor_unsupported = B_FALSE; 4301 } /* audiohd_build_monitor_path */ 4302 4303 /* 4304 * audiohd_do_finish_monitor_path 4305 * 4306 * Description: 4307 * Enable the widgets on the monitor path 4308 */ 4309 static void 4310 audiohd_do_finish_monitor_path(hda_codec_t *codec, audiohd_widget_t *wgt) 4311 { 4312 uint_t caddr = codec->index; 4313 audiohd_widget_t *widget = wgt; 4314 audiohd_widget_t *w; 4315 audiohd_state_t *statep = codec->soft_statep; 4316 wid_t wid; 4317 int i; 4318 int share = 0; 4319 4320 if (!widget || widget->finish) 4321 return; 4322 if (widget->path_flags & AUDIOHD_PATH_ADC) 4323 share = 1; 4324 if ((widget->outamp_cap)&&!share) 4325 (void) audioha_codec_4bit_verb_get(statep, caddr, 4326 widget->wid_wid, 4327 AUDIOHDC_VERB_SET_AMP_MUTE, 4328 AUDIOHDC_AMP_SET_LR_OUTPUT 4329 | AUDIOHDC_GAIN_MAX); 4330 if ((widget->inamp_cap)&&!share) { 4331 for (i = 0; i < widget->used; i++) { 4332 (void) audioha_codec_4bit_verb_get(statep, caddr, 4333 widget->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE, 4334 AUDIOHDC_AMP_SET_LR_INPUT | 4335 AUDIOHDC_GAIN_MAX | 4336 (widget->selmon[i] << 4337 AUDIOHDC_AMP_SET_INDEX_OFFSET)); 4338 } 4339 } 4340 if ((widget->type == WTYPE_AUDIO_SEL) && (widget->nconns > 1) && 4341 !share) { 4342 (void) audioha_codec_verb_get(statep, caddr, 4343 widget->wid_wid, 4344 AUDIOHDC_VERB_SET_CONN_SEL, widget->selmon[0]); 4345 } 4346 widget->finish = 1; 4347 if (widget->used == 0) 4348 return; 4349 if (widget->used > 0) { 4350 for (i = 0; i < widget->used; i++) { 4351 wid = widget->avail_conn[widget->selmon[i]]; 4352 w = codec->widget[wid]; 4353 audiohd_do_finish_monitor_path(codec, w); 4354 } 4355 } 4356 } /* audiohd_do_finish_monitor_path */ 4357 4358 /* 4359 * audiohd_finish_monitor_path 4360 * 4361 * Description: 4362 * Enable the monitor path for every ostream path 4363 */ 4364 static void 4365 audiohd_finish_monitor_path(hda_codec_t *codec) 4366 { 4367 audiohd_path_t *path; 4368 audiohd_widget_t *widget; 4369 audiohd_state_t *statep = codec->soft_statep; 4370 wid_t wid; 4371 int i, j, k; 4372 4373 for (i = 0; i < statep->pathnum; i++) { 4374 path = statep->path[i]; 4375 if (!path || path->codec != codec || path->path_type != PLAY) 4376 continue; 4377 for (j = 0; j < path->pin_nums; j++) { 4378 for (k = 0; k < path->maxmixer[j]; k++) { 4379 wid = path->mon_wid[j][k]; 4380 if (wid == 0) { 4381 continue; 4382 } 4383 widget = codec->widget[wid]; 4384 audiohd_do_finish_monitor_path(codec, widget); 4385 } 4386 } 4387 } 4388 } /* audiohd_finish_monitor_path */ 4389 4390 /* 4391 * audiohd_do_build_monit_amp() 4392 * 4393 * Description: 4394 * Search for the gain control widget for the monitor path 4395 */ 4396 static void 4397 audiohd_do_build_monitor_amp(hda_codec_t *codec, audiohd_pin_t *pin, 4398 audiohd_widget_t *widget) 4399 { 4400 audiohd_widget_t *w = widget; 4401 uint32_t gain; 4402 int i; 4403 wid_t wid; 4404 4405 if (!w || 4406 (w->type == WTYPE_PIN) || 4407 !w->used || 4408 (pin->num == AUDIOHD_MAX_CONN) || 4409 (w->path_flags & AUDIOHD_PATH_ADC)) 4410 return; 4411 if (!(w->path_flags & AUDIOHD_PATH_DAC)) { 4412 gain = w->outamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS; 4413 if (gain) { 4414 pin->mg_dir[pin->num] = AUDIOHDC_AMP_SET_OUTPUT; 4415 pin->mg_gain[pin->num] = gain; 4416 pin->mg_wid[pin->num] = w->wid_wid; 4417 pin->mg_gain[pin->num] >>= AUDIOHD_GAIN_OFF; 4418 pin->num++; 4419 return; 4420 } 4421 gain = w->inamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS; 4422 if (gain) { 4423 pin->mg_dir[pin->num] = AUDIOHDC_AMP_SET_INPUT; 4424 pin->mg_gain[pin->num] = gain; 4425 pin->mg_wid[pin->num] = w->wid_wid; 4426 pin->mg_gain[pin->num] >>= AUDIOHD_GAIN_OFF; 4427 pin->num++; 4428 return; 4429 } 4430 } 4431 for (i = 0; i < w->used; i++) { 4432 wid = w->avail_conn[w->selmon[i]]; 4433 audiohd_do_build_monitor_amp(codec, pin, codec->widget[wid]); 4434 } 4435 4436 4437 } /* audiohd_do_build_monitor_amp() */ 4438 4439 /* 4440 * audiohd_build_monitor_amp() 4441 * 4442 * Description: 4443 * Search gain control widget for every ostream monitor 4444 */ 4445 static void 4446 audiohd_build_monitor_amp(hda_codec_t *codec) 4447 { 4448 audiohd_path_t *path; 4449 audiohd_widget_t *widget, *w; 4450 audiohd_state_t *statep = codec->soft_statep; 4451 audiohd_pin_t *pin; 4452 wid_t wid, id; 4453 int i, j, k; 4454 4455 for (i = 0; i < statep->pathnum; i++) { 4456 path = statep->path[i]; 4457 if (!path || path->codec != codec || path->path_type != PLAY) 4458 continue; 4459 for (j = 0; j < path->pin_nums; j++) { 4460 id = path->pin_wid[j]; 4461 w = codec->widget[id]; 4462 pin = (audiohd_pin_t *)(w->priv); 4463 for (k = 0; k < path->maxmixer[j]; k++) { 4464 wid = path->mon_wid[j][k]; 4465 if (!wid) 4466 continue; 4467 widget = codec->widget[wid]; 4468 audiohd_do_build_monitor_amp(codec, pin, 4469 widget); 4470 } 4471 } 4472 } 4473 } 4474 4475 4476 /* 4477 * audiohd_build_path() 4478 * 4479 * Description: 4480 * Here we build the output, input, monitor path. 4481 * And also enable the path in default. 4482 * Search for the gain and mute control for the path 4483 */ 4484 static void 4485 audiohd_build_path(audiohd_state_t *statep) 4486 { 4487 int i; 4488 4489 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 4490 if (statep->codec[i]) { 4491 audiohd_build_output_path(statep->codec[i]); 4492 audiohd_build_output_amp(statep->codec[i]); 4493 audiohd_finish_output_path(statep->codec[i]); 4494 4495 audiohd_build_input_path(statep->codec[i]); 4496 audiohd_build_input_amp(statep->codec[i]); 4497 audiohd_finish_input_path(statep->codec[i]); 4498 4499 audiohd_build_monitor_path(statep->codec[i]); 4500 audiohd_build_monitor_amp(statep->codec[i]); 4501 audiohd_finish_monitor_path(statep->codec[i]); 4502 } 4503 } 4504 } /* audiohd_build_path */ 4505 4506 /* 4507 * audiohd_allocate_port() 4508 */ 4509 static int 4510 audiohd_allocate_port(audiohd_state_t *statep) 4511 { 4512 int i, j; 4513 audiohd_port_t *port; 4514 int dir; 4515 unsigned caps; 4516 char *prop; 4517 int rc; 4518 audio_dev_t *adev; 4519 dev_info_t *dip; 4520 ddi_dma_cookie_t cookie; 4521 uint_t count; 4522 uint64_t buf_phys_addr; 4523 sd_bdle_t *entry; 4524 uint16_t gcap; 4525 size_t real_size; 4526 4527 adev = statep->adev; 4528 dip = statep->hda_dip; 4529 4530 ddi_dma_attr_t dma_attr = { 4531 DMA_ATTR_V0, /* version */ 4532 0, /* addr_lo */ 4533 0xffffffffffffffffULL, /* addr_hi */ 4534 0x00000000ffffffffULL, /* count_max */ 4535 128, /* 128-byte alignment as HD spec */ 4536 0xfff, /* burstsize */ 4537 1, /* minxfer */ 4538 0xffffffff, /* maxxfer */ 4539 0xffffffff, /* seg */ 4540 1, /* sgllen */ 4541 1, /* granular */ 4542 0 /* flags */ 4543 }; 4544 4545 gcap = AUDIOHD_REG_GET16(AUDIOHD_REG_GCAP); 4546 if ((gcap & AUDIOHDR_GCAP_64OK) == 0) 4547 dma_attr.dma_attr_addr_hi = 0xffffffffUL; 4548 4549 for (i = 0; i < PORT_MAX; i++) { 4550 port = kmem_zalloc(sizeof (*port), KM_SLEEP); 4551 port->started = B_FALSE; 4552 port->triggered = B_FALSE; 4553 statep->port[i] = port; 4554 port->statep = statep; 4555 switch (i) { 4556 case PORT_ADC: 4557 prop = "record-interrupts"; 4558 dir = DDI_DMA_READ | DDI_DMA_CONSISTENT; 4559 caps = ENGINE_INPUT_CAP; 4560 port->sync_dir = DDI_DMA_SYNC_FORKERNEL; 4561 port->nchan = statep->rchan; 4562 port->index = 1; 4563 port->regoff = AUDIOHD_REG_SD_BASE; 4564 break; 4565 case PORT_DAC: 4566 prop = "play-interrupts"; 4567 dir = DDI_DMA_WRITE | DDI_DMA_CONSISTENT; 4568 caps = ENGINE_OUTPUT_CAP; 4569 port->sync_dir = DDI_DMA_SYNC_FORDEV; 4570 port->nchan = statep->pchan; 4571 port->index = statep->hda_input_streams + 1; 4572 port->regoff = AUDIOHD_REG_SD_BASE + 4573 AUDIOHD_REG_SD_LEN * 4574 statep->hda_input_streams; 4575 break; 4576 default: 4577 return (DDI_FAILURE); 4578 } 4579 4580 port->intrs = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 4581 DDI_PROP_DONTPASS, prop, AUDIOHD_INTS); 4582 4583 /* make sure the values are good */ 4584 if (port->intrs < AUDIOHD_MIN_INTS) { 4585 audio_dev_warn(adev, "%s too low, %d, resetting to %d", 4586 prop, port->intrs, AUDIOHD_INTS); 4587 port->intrs = AUDIOHD_INTS; 4588 } else if (port->intrs > AUDIOHD_MAX_INTS) { 4589 audio_dev_warn(adev, "%s too high, %d, resetting to %d", 4590 prop, port->intrs, AUDIOHD_INTS); 4591 port->intrs = AUDIOHD_INTS; 4592 } 4593 4594 port->format = AUDIOHD_FMT_PCM; 4595 port->fragfr = 48000 / port->intrs; 4596 port->fragfr = (port->fragfr + AUDIOHD_FRAGFR_ALIGN - 1) & ~ 4597 (AUDIOHD_FRAGFR_ALIGN - 1); 4598 port->samp_size = port->fragfr * port->nchan * 2; 4599 port->samp_size = (port->samp_size + 4600 AUDIOHD_BDLE_BUF_ALIGN - 1) & ~ 4601 (AUDIOHD_BDLE_BUF_ALIGN - 1); 4602 4603 /* allocate dma handle */ 4604 rc = ddi_dma_alloc_handle(dip, &dma_attr, DDI_DMA_SLEEP, 4605 NULL, &port->samp_dmah); 4606 if (rc != DDI_SUCCESS) { 4607 audio_dev_warn(adev, "ddi_dma_alloc_handle failed: %d", 4608 rc); 4609 goto error_alloc_dma_exit1; 4610 } 4611 /* allocate DMA buffer */ 4612 rc = ddi_dma_mem_alloc(port->samp_dmah, port->samp_size * 4613 AUDIOHD_BDLE_NUMS, 4614 &hda_dev_accattr, 4615 DDI_DMA_CONSISTENT, 4616 DDI_DMA_SLEEP, NULL, &port->samp_kaddr, 4617 &real_size, &port->samp_acch); 4618 if (rc == DDI_FAILURE) { 4619 audio_dev_warn(adev, "dma_mem_alloc failed"); 4620 goto error_alloc_dma_exit2; 4621 } 4622 4623 /* bind DMA buffer */ 4624 rc = ddi_dma_addr_bind_handle(port->samp_dmah, NULL, 4625 port->samp_kaddr, real_size, dir, 4626 DDI_DMA_SLEEP, NULL, &cookie, &count); 4627 if ((rc != DDI_DMA_MAPPED) || (count != 1)) { 4628 audio_dev_warn(adev, 4629 "ddi_dma_addr_bind_handle failed: %d", rc); 4630 goto error_alloc_dma_exit3; 4631 } 4632 port->samp_paddr = (uint64_t)cookie.dmac_laddress; 4633 4634 /* 4635 * now, from here we allocate DMA 4636 * memory for buffer descriptor list. 4637 * we allocate adjacent DMA memory for all DMA engines. 4638 */ 4639 rc = ddi_dma_alloc_handle(dip, &dma_attr, DDI_DMA_SLEEP, 4640 NULL, &port->bdl_dmah); 4641 if (rc != DDI_SUCCESS) { 4642 audio_dev_warn(adev, 4643 "ddi_dma_alloc_handle(bdlist) failed"); 4644 goto error_alloc_dma_exit3; 4645 } 4646 4647 /* 4648 * we allocate all buffer descriptors lists in continuous 4649 * dma memory. 4650 */ 4651 port->bdl_size = sizeof (sd_bdle_t) * AUDIOHD_BDLE_NUMS; 4652 rc = ddi_dma_mem_alloc(port->bdl_dmah, port->bdl_size, 4653 &hda_dev_accattr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 4654 &port->bdl_kaddr, &real_size, &port->bdl_acch); 4655 if (rc != DDI_SUCCESS) { 4656 audio_dev_warn(adev, 4657 "ddi_dma_mem_alloc(bdlist) failed"); 4658 goto error_alloc_dma_exit4; 4659 } 4660 4661 rc = ddi_dma_addr_bind_handle(port->bdl_dmah, NULL, 4662 port->bdl_kaddr, 4663 real_size, DDI_DMA_WRITE | DDI_DMA_CONSISTENT, 4664 DDI_DMA_SLEEP, 4665 NULL, &cookie, &count); 4666 if ((rc != DDI_DMA_MAPPED) || (count != 1)) { 4667 audio_dev_warn(adev, "addr_bind_handle failed"); 4668 goto error_alloc_dma_exit5; 4669 } 4670 port->bdl_paddr = (uint64_t)cookie.dmac_laddress; 4671 4672 entry = (sd_bdle_t *)port->bdl_kaddr; 4673 buf_phys_addr = port->samp_paddr; 4674 4675 for (j = 0; j < AUDIOHD_BDLE_NUMS; j++) { 4676 entry->sbde_addr = buf_phys_addr; 4677 entry->sbde_len = port->samp_size; 4678 entry->sbde_ioc = 1; 4679 buf_phys_addr += port->samp_size; 4680 entry++; 4681 } 4682 (void) ddi_dma_sync(port->bdl_dmah, 0, sizeof (sd_bdle_t) * 4683 AUDIOHD_BDLE_NUMS, DDI_DMA_SYNC_FORDEV); 4684 port->curpos = 0; 4685 4686 port->engine = audio_engine_alloc(&audiohd_engine_ops, caps); 4687 if (port->engine == NULL) { 4688 audio_dev_warn(adev, "audio_engine_alloc failed"); 4689 goto error_alloc_dma_exit5; 4690 } 4691 4692 audio_engine_set_private(port->engine, port); 4693 audio_dev_add_engine(adev, port->engine); 4694 } 4695 4696 return (DDI_SUCCESS); 4697 error_alloc_dma_exit5: 4698 ddi_dma_mem_free(&port->bdl_acch); 4699 4700 error_alloc_dma_exit4: 4701 ddi_dma_free_handle(&port->bdl_dmah); 4702 4703 error_alloc_dma_exit3: 4704 ddi_dma_mem_free(&port->samp_acch); 4705 4706 error_alloc_dma_exit2: 4707 ddi_dma_free_handle(&port->samp_dmah); 4708 4709 error_alloc_dma_exit1: 4710 return (AUDIO_FAILURE); 4711 4712 } 4713 4714 static void 4715 audiohd_free_port(audiohd_state_t *statep) 4716 { 4717 int i; 4718 audiohd_port_t *port; 4719 4720 if (statep == NULL) { 4721 return; 4722 } 4723 for (i = 0; i < PORT_MAX; i++) { 4724 port = statep->port[i]; 4725 if (port == NULL) 4726 continue; 4727 if (port->engine) { 4728 audio_dev_remove_engine(statep->adev, 4729 port->engine); 4730 audio_engine_free(port->engine); 4731 } 4732 if (port->samp_dmah) { 4733 (void) ddi_dma_unbind_handle(port->samp_dmah); 4734 } 4735 if (port->samp_acch) { 4736 ddi_dma_mem_free(&port->samp_acch); 4737 } 4738 if (port->samp_dmah) { 4739 ddi_dma_free_handle(&port->samp_dmah); 4740 } 4741 if (port->bdl_dmah) { 4742 (void) ddi_dma_unbind_handle(port->bdl_dmah); 4743 } 4744 if (port->bdl_acch) { 4745 ddi_dma_mem_free(&port->bdl_acch); 4746 } 4747 if (port->bdl_dmah) { 4748 ddi_dma_free_handle(&port->bdl_dmah); 4749 } 4750 4751 kmem_free(port, sizeof (audiohd_port_t)); 4752 } 4753 } 4754 4755 /* 4756 * audiohd_change_widget_power_state(audiohd_state_t *statep, int off) 4757 * Description: 4758 * This routine is used to change the widget power betwen D0 and D2. 4759 * D0 is fully on; D2 allows the lowest possible power consuming state 4760 * from which it can return to the fully on state: D0. 4761 */ 4762 static void 4763 audiohd_change_widget_power_state(audiohd_state_t *statep, int off) 4764 { 4765 int i; 4766 wid_t wid; 4767 hda_codec_t *codec; 4768 audiohd_widget_t *widget; 4769 4770 /* Change power to D2 */ 4771 if (off) { 4772 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 4773 codec = statep->codec[i]; 4774 if (!codec) 4775 continue; 4776 for (wid = codec->first_wid; wid <= codec->last_wid; 4777 wid++) { 4778 widget = codec->widget[wid]; 4779 if (widget->widget_cap & 4780 AUDIOHD_WIDCAP_PWRCTRL) { 4781 (void) audioha_codec_verb_get(statep, 4782 codec->index, wid, 4783 AUDIOHDC_VERB_SET_POWER_STATE, 4784 AUDIOHD_PW_D2); 4785 } 4786 } 4787 } 4788 /* Change power to D0 */ 4789 } else { 4790 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 4791 codec = statep->codec[i]; 4792 if (!codec) 4793 continue; 4794 for (wid = codec->first_wid; wid <= codec->last_wid; 4795 wid++) { 4796 widget = codec->widget[wid]; 4797 if (widget->widget_cap & 4798 AUDIOHD_WIDCAP_PWRCTRL) { 4799 (void) audioha_codec_verb_get(statep, 4800 codec->index, wid, 4801 AUDIOHDC_VERB_SET_POWER_STATE, 4802 AUDIOHD_PW_D0); 4803 } 4804 } 4805 } 4806 } 4807 } 4808 /* 4809 * audiohd_restore_path() 4810 * Description: 4811 * This routine is used to restore the path on the codec. 4812 */ 4813 static void 4814 audiohd_restore_path(audiohd_state_t *statep) 4815 { 4816 int i; 4817 hda_codec_t *codec; 4818 4819 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 4820 codec = statep->codec[i]; 4821 if (!codec) 4822 continue; 4823 audiohd_finish_output_path(statep->codec[i]); 4824 audiohd_finish_input_path(statep->codec[i]); 4825 audiohd_finish_monitor_path(statep->codec[i]); 4826 } 4827 } 4828 4829 /* 4830 * restore_play_and_record() 4831 */ 4832 static void 4833 audiohd_restore_play_and_record(audiohd_state_t *statep) 4834 { 4835 int i; 4836 audiohd_port_t *port; 4837 4838 mutex_enter(&statep->hda_mutex); 4839 for (i = 0; i < PORT_MAX; i++) { 4840 port = statep->port[i]; 4841 if (port == NULL) 4842 continue; 4843 if (port != NULL) 4844 audio_engine_reset(port->engine); 4845 if (port->triggered) { 4846 (void) audiohd_reset_port(port); 4847 audiohd_start_port(port); 4848 } else { 4849 audiohd_stop_port(port); 4850 4851 } 4852 } 4853 mutex_exit(&statep->hda_mutex); 4854 } 4855 /* 4856 * audiohd_reset_pins_ur_cap() 4857 * Description: 4858 * Enable the unsolicited response of the pins which have the unsolicited 4859 * response capability 4860 */ 4861 static void 4862 audiohd_reset_pins_ur_cap(audiohd_state_t *statep) 4863 { 4864 hda_codec_t *codec; 4865 audiohd_pin_t *pin; 4866 audiohd_widget_t *widget; 4867 uint32_t urctrl; 4868 int i; 4869 4870 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 4871 codec = statep->codec[i]; 4872 if (!codec) 4873 continue; 4874 pin = codec->first_pin; 4875 while (pin) { 4876 /* enable the unsolicited response of the pin */ 4877 widget = codec->widget[pin->wid]; 4878 if ((widget->widget_cap & 4879 (AUDIOHD_URCAP_MASK) && 4880 (pin->cap & AUDIOHD_DTCCAP_MASK)) && 4881 ((pin->device == DTYPE_LINEOUT) || 4882 (pin->device == DTYPE_SPDIF_OUT) || 4883 (pin->device == DTYPE_HP_OUT) || 4884 (pin->device == DTYPE_MIC_IN))) { 4885 urctrl = (uint8_t)(1 << 4886 (AUDIOHD_UR_ENABLE_OFF - 1)); 4887 urctrl |= (pin->wid & AUDIOHD_UR_TAG_MASK); 4888 (void) audioha_codec_verb_get(statep, 4889 codec->index, 4890 pin->wid, 4891 AUDIOHDC_VERB_SET_URCTRL, urctrl); 4892 } 4893 pin = pin->next; 4894 } 4895 } 4896 } 4897 static void 4898 audiohd_restore_codec_gpio(audiohd_state_t *statep) 4899 { 4900 int i; 4901 wid_t wid; 4902 hda_codec_t *codec; 4903 4904 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 4905 codec = statep->codec[i]; 4906 if (codec == NULL) 4907 continue; 4908 wid = codec->wid_afg; 4909 4910 /* power-up audio function group */ 4911 (void) audioha_codec_verb_get(statep, i, wid, 4912 AUDIOHDC_VERB_SET_POWER_STATE, 0); 4913 /* work around for Sony VAIO laptop with specific codec */ 4914 if ((codec->vid != AUDIOHD_CODECID_SONY1) && 4915 (codec->vid != AUDIOHD_CODECID_SONY2)) { 4916 /* 4917 * GPIO controls which are laptop specific workarounds 4918 * and might be changed. Some laptops use GPIO, 4919 * so we need to enable and set the GPIO correctly. 4920 */ 4921 (void) audioha_codec_verb_get(statep, i, wid, 4922 AUDIOHDC_VERB_SET_GPIO_MASK, AUDIOHDC_GPIO_ENABLE); 4923 (void) audioha_codec_verb_get(statep, i, wid, 4924 AUDIOHDC_VERB_SET_GPIO_DIREC, AUDIOHDC_GPIO_DIRECT); 4925 (void) audioha_codec_verb_get(statep, i, wid, 4926 AUDIOHDC_VERB_SET_GPIO_STCK, 4927 AUDIOHDC_GPIO_DATA_CTRL); 4928 (void) audioha_codec_verb_get(statep, i, wid, 4929 AUDIOHDC_VERB_SET_GPIO_DATA, 4930 AUDIOHDC_GPIO_STCK_CTRL); 4931 } 4932 } 4933 } 4934 /* 4935 * audiohd_resume() 4936 */ 4937 static int 4938 audiohd_resume(audiohd_state_t *statep) 4939 { 4940 uint8_t rirbsts; 4941 4942 mutex_enter(&statep->hda_mutex); 4943 statep->suspended = B_FALSE; 4944 /* Restore the hda state */ 4945 if (audiohd_reinit_hda(statep) == AUDIO_FAILURE) { 4946 audio_dev_warn(statep->adev, 4947 "hda reinit failed"); 4948 mutex_exit(&statep->hda_mutex); 4949 return (DDI_SUCCESS); 4950 } 4951 /* reset to enable the capability of unsolicited response for pin */ 4952 audiohd_reset_pins_ur_cap(statep); 4953 /* Enable interrupt */ 4954 AUDIOHD_REG_SET32(AUDIOHD_REG_INTCTL, 4955 AUDIOHD_INTCTL_BIT_GIE | 4956 AUDIOHD_INTCTL_BIT_SIE); 4957 /* clear the unsolicited response interrupt */ 4958 rirbsts = AUDIOHD_REG_GET8(AUDIOHD_REG_RIRBSTS); 4959 AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBSTS, rirbsts); 4960 mutex_exit(&statep->hda_mutex); 4961 4962 audiohd_restore_play_and_record(statep); 4963 audiohd_configure_output(statep); 4964 audiohd_restore_volume(statep); 4965 audiohd_configure_input(statep); 4966 4967 /* set widget power to D0 */ 4968 audiohd_change_widget_power_state(statep, AUDIOHD_PW_ON); 4969 4970 return (DDI_SUCCESS); 4971 } /* audiohd_resume */ 4972 4973 /* 4974 * audiohd_suspend() 4975 */ 4976 static int 4977 audiohd_suspend(audiohd_state_t *statep) 4978 { 4979 mutex_enter(&statep->hda_mutex); 4980 statep->suspended = B_TRUE; 4981 4982 /* set widget power to D2 */ 4983 audiohd_change_widget_power_state(statep, AUDIOHD_PW_OFF); 4984 /* Disable h/w */ 4985 audiohd_disable_intr(statep); 4986 audiohd_stop_dma(statep); 4987 mutex_exit(&statep->hda_mutex); 4988 4989 return (DDI_SUCCESS); 4990 } /* audiohd_suspend */ 4991 4992 /* 4993 * audiohd_disable_pin() 4994 */ 4995 static int 4996 audiohd_disable_pin(audiohd_state_t *statep, int caddr, wid_t wid) 4997 { 4998 AUDIOHD_DISABLE_PIN_OUT(statep, caddr, wid); 4999 return (AUDIO_SUCCESS); 5000 } 5001 5002 /* 5003 * audiohd_enable_pin() 5004 */ 5005 static int 5006 audiohd_enable_pin(audiohd_state_t *statep, int caddr, wid_t wid) 5007 { 5008 AUDIOHD_ENABLE_PIN_OUT(statep, caddr, wid); 5009 return (AUDIO_SUCCESS); 5010 } 5011 /* 5012 * audiohd_change_speaker_state() 5013 */ 5014 static void 5015 audiohd_change_speaker_state(audiohd_state_t *statep, int on) 5016 { 5017 audiohd_path_t *path; 5018 audiohd_widget_t *widget; 5019 audiohd_pin_t *pin; 5020 int i, j; 5021 wid_t wid; 5022 5023 for (i = 0; i < statep->pathnum; i++) { 5024 path = statep->path[i]; 5025 if (!path || path->path_type != PLAY) 5026 continue; 5027 if (on) { 5028 for (j = 0; j < path->pin_nums; j++) { 5029 wid = path->pin_wid[j]; 5030 widget = path->codec->widget[wid]; 5031 pin = (audiohd_pin_t *)widget->priv; 5032 if (pin->device == DTYPE_SPEAKER) { 5033 (void) audiohd_enable_pin( 5034 statep, 5035 path->codec->index, 5036 pin->wid); 5037 } 5038 } 5039 5040 } else { 5041 for (j = 0; j < path->pin_nums; j++) { 5042 wid = path->pin_wid[j]; 5043 widget = path->codec->widget[wid]; 5044 pin = (audiohd_pin_t *)widget->priv; 5045 if (pin->device == DTYPE_SPEAKER) { 5046 (void) audiohd_disable_pin( 5047 statep, 5048 path->codec->index, 5049 pin->wid); 5050 } 5051 } 5052 } 5053 } 5054 } 5055 /* 5056 * audiohd_select_mic() 5057 * 5058 * Description: 5059 * This function is used for the recording path which has a selector 5060 * as the sumwidget. We select the external MIC if it is plugged into the 5061 * MIC jack, otherwise the internal integrated MIC is selected. 5062 */ 5063 static void 5064 audiohd_select_mic(audiohd_state_t *statep, uint8_t index, 5065 uint8_t id, int select) 5066 { 5067 hda_codec_t *codec; 5068 audiohd_path_t *path; 5069 audiohd_widget_t *widget, *sumwgt; 5070 audiohd_pin_t *pin; 5071 int i, j; 5072 wid_t wid; 5073 5074 codec = statep->codec[index]; 5075 if (codec == NULL) 5076 return; 5077 for (i = 0; i < statep->pathnum; i++) { 5078 path = statep->path[i]; 5079 if (path->codec != codec || path->path_type != RECORD) 5080 continue; 5081 sumwgt = codec->widget[path->sum_wid]; 5082 if (path && sumwgt && 5083 (sumwgt->type == WTYPE_AUDIO_SEL)) { 5084 for (j = 0; j < path->pin_nums; j++) { 5085 wid = path->pin_wid[j]; 5086 widget = codec->widget[wid]; 5087 if (widget == NULL) 5088 return; 5089 pin = (audiohd_pin_t *)widget->priv; 5090 if (select && 5091 pin->device == DTYPE_MIC_IN && 5092 pin->wid == id && 5093 (((pin->config >> 5094 AUDIOHD_PIN_CONTP_OFF) & 5095 AUDIOHD_PIN_CONTP_MASK) == 5096 AUDIOHD_PIN_CON_JACK)) { 5097 (void) audioha_codec_verb_get( 5098 statep, 5099 index, 5100 path->sum_wid, 5101 AUDIOHDC_VERB_SET_CONN_SEL, 5102 path->sum_selconn[j]); 5103 statep->port[PORT_ADC]->index = 5104 path->tag; 5105 return; 5106 } else if (!select && 5107 pin->device == DTYPE_MIC_IN && 5108 pin->wid == id && 5109 (((pin->config >> 5110 AUDIOHD_PIN_CONTP_OFF) & 5111 AUDIOHD_PIN_CONTP_MASK) == 5112 AUDIOHD_PIN_CON_JACK)) { 5113 (void) audioha_codec_verb_get( 5114 statep, 5115 index, 5116 path->sum_wid, 5117 AUDIOHDC_VERB_SET_CONN_SEL, 5118 path->sum_selconn[j]); 5119 statep->port[PORT_ADC]->index = 5120 path->tag; 5121 return; 5122 } 5123 } 5124 if (path == NULL) 5125 break; 5126 sumwgt = codec->widget[path->sum_wid]; 5127 } 5128 } 5129 /* 5130 * If the input istream > 1, we should set the record stream tag 5131 * respectively. All the input streams sharing one tag may make the 5132 * record sound distorted. 5133 */ 5134 if (codec->nistream > 1) { 5135 for (i = 0; i < statep->pathnum; i++) { 5136 path = statep->path[i]; 5137 if (!path || path->path_type != RECORD) 5138 continue; 5139 for (j = 0; j < path->pin_nums; j++) { 5140 wid = path->pin_wid[j]; 5141 widget = codec->widget[wid]; 5142 if (widget == NULL) 5143 return; 5144 pin = (audiohd_pin_t *)widget->priv; 5145 if (select && 5146 pin->device == DTYPE_MIC_IN && 5147 pin->wid == id && 5148 (((pin->config >> 5149 AUDIOHD_PIN_CONTP_OFF) & 5150 AUDIOHD_PIN_CONTP_MASK) == 5151 AUDIOHD_PIN_CON_JACK)) { 5152 statep->port[PORT_ADC]->index = 5153 path->tag; 5154 return; 5155 } else if (!select && 5156 pin->device == DTYPE_MIC_IN && 5157 (((pin->config >> 5158 AUDIOHD_PIN_CONTP_OFF) & 5159 AUDIOHD_PIN_CONTP_MASK) == 5160 AUDIOHD_PIN_CON_FIXED)) { 5161 statep->port[PORT_ADC]->index = 5162 path->tag; 5163 return; 5164 } 5165 } 5166 } 5167 } 5168 } 5169 /* 5170 * audiohd_pin_sense() 5171 * 5172 * Description 5173 * 5174 * When the earphone is plugged into the jack associtated with the pin 5175 * complex, we disable the built in speaker. When the earphone is plugged 5176 * out of the jack, we enable the built in speaker. 5177 */ 5178 static void 5179 audiohd_pin_sense(audiohd_state_t *statep, uint32_t resp, uint32_t respex) 5180 { 5181 uint8_t index; 5182 uint8_t id; 5183 uint32_t rs; 5184 audiohd_widget_t *widget; 5185 audiohd_pin_t *pin; 5186 hda_codec_t *codec; 5187 5188 index = respex & AUDIOHD_RIRB_CODEC_MASK; 5189 id = resp >> (AUDIOHD_RIRB_WID_OFF - 1); 5190 5191 codec = statep->codec[index]; 5192 if (codec == NULL) 5193 return; 5194 widget = codec->widget[id]; 5195 if (widget == NULL) 5196 return; 5197 5198 rs = audioha_codec_verb_get(statep, index, id, 5199 AUDIOHDC_VERB_GET_PIN_SENSE, 0); 5200 if (rs >> (AUDIOHD_PIN_PRES_OFF - 1) & 1) { 5201 /* A MIC is plugged in, we select the MIC as input */ 5202 if ((widget->type == WTYPE_PIN) && 5203 (pin = (audiohd_pin_t *)widget->priv) && 5204 (pin->device == DTYPE_MIC_IN)) { 5205 audiohd_select_mic(statep, index, id, 1); 5206 return; 5207 } 5208 /* output pin is plugged */ 5209 audiohd_change_speaker_state(statep, AUDIOHD_SP_OFF); 5210 } else { 5211 /* 5212 * A MIC is unplugged, we select the built in MIC 5213 * as input. 5214 */ 5215 if ((widget->type == WTYPE_PIN) && 5216 (pin = (audiohd_pin_t *)widget->priv) && 5217 (pin->device == DTYPE_MIC_IN)) { 5218 audiohd_select_mic(statep, index, id, 0); 5219 return; 5220 } 5221 /* output pin is unplugged */ 5222 audiohd_change_speaker_state(statep, AUDIOHD_SP_ON); 5223 } 5224 5225 } 5226 /* 5227 * audiohd_intr() 5228 * 5229 * Description 5230 * 5231 * 5232 * Arguments: 5233 * caddr_t arg Pointer to the interrupting device's state 5234 * structure 5235 * 5236 * Returns: 5237 * DDI_INTR_CLAIMED Interrupt claimed and processed 5238 * DDI_INTR_UNCLAIMED Interrupt not claimed, and thus ignored 5239 */ 5240 static uint_t 5241 audiohd_intr(caddr_t arg) 5242 { 5243 audiohd_state_t *statep = (audiohd_state_t *)arg; 5244 uint32_t status; 5245 uint32_t regbase; 5246 uint32_t resp, respex; 5247 uint8_t sdstatus, rirbsts; 5248 int i, ret; 5249 audio_engine_t *do_adc = NULL; 5250 audio_engine_t *do_dac = NULL; 5251 5252 5253 mutex_enter(&statep->hda_mutex); 5254 if (statep->suspended) { 5255 mutex_exit(&statep->hda_mutex); 5256 return (DDI_INTR_UNCLAIMED); 5257 } 5258 5259 status = AUDIOHD_REG_GET32(AUDIOHD_REG_INTSTS); 5260 if (status == 0) { 5261 mutex_exit(&statep->hda_mutex); 5262 return (DDI_INTR_UNCLAIMED); 5263 } 5264 AUDIOHD_REG_SET32(AUDIOHD_REG_INTSTS, status); 5265 5266 /* 5267 * unsolicited response from pins, maybe something plugged in or out 5268 * of the jack. 5269 */ 5270 if (status & AUDIOHD_CIS_MASK) { 5271 /* clear the unsolicited response interrupt */ 5272 rirbsts = AUDIOHD_REG_GET8(AUDIOHD_REG_RIRBSTS); 5273 AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBSTS, rirbsts); 5274 /* 5275 * We have to wait and try several times to make sure the 5276 * unsolicited response is generated by our pins. 5277 * we need to make it work for audiohd spec 0.9, which is 5278 * just a draft version and requires more time to wait. 5279 */ 5280 for (i = 0; i < AUDIOHD_TEST_TIMES; i++) { 5281 ret = audiohd_response_from_codec(statep, &resp, 5282 &respex); 5283 if ((ret == AUDIO_SUCCESS) && 5284 (respex & AUDIOHD_RIRB_UR_MASK)) { 5285 /* 5286 * A pin may generate more than one ur rirb, 5287 * we only need handle one of them, and clear 5288 * the other ones 5289 */ 5290 statep->hda_rirb_rp = 5291 AUDIOHD_REG_GET16(AUDIOHD_REG_RIRBWP) & 5292 AUDIOHD_RIRB_WPMASK; 5293 break; 5294 } 5295 } 5296 if ((ret == AUDIO_SUCCESS) && 5297 (respex & AUDIOHD_RIRB_UR_MASK)) { 5298 audiohd_pin_sense(statep, resp, respex); 5299 } 5300 } 5301 5302 /* stream intr */ 5303 for (i = 0; i < statep->hda_streams_nums; i++) { 5304 if ((status & (1<<i)) == 0) 5305 continue; 5306 5307 regbase = AUDIOHD_REG_SD_BASE + AUDIOHD_REG_SD_LEN * i; 5308 sdstatus = AUDIOHD_REG_GET8(regbase + AUDIOHD_SDREG_OFFSET_STS); 5309 5310 /* clear intrs */ 5311 AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_STS, sdstatus); 5312 if (i < statep->hda_input_streams) 5313 do_adc = statep->port[PORT_ADC]->engine; 5314 else 5315 do_dac = statep->port[PORT_DAC]->engine; 5316 } 5317 5318 /* update the kernel interrupt statistics */ 5319 if (statep->hda_ksp) { 5320 ((kstat_intr_t *) 5321 (statep->hda_ksp->ks_data))->intrs[KSTAT_INTR_HARD]++; 5322 } 5323 5324 mutex_exit(&statep->hda_mutex); 5325 5326 if (do_adc) 5327 audio_engine_produce(do_adc); 5328 if (do_dac) 5329 audio_engine_consume(do_dac); 5330 return (DDI_INTR_CLAIMED); 5331 } /* audiohd_intr() */ 5332 5333 /* 5334 * audiohd_disable_intr() 5335 * 5336 * Description: 5337 * Disable all possible interrupts. 5338 */ 5339 static void 5340 audiohd_disable_intr(audiohd_state_t *statep) 5341 { 5342 int i; 5343 uint32_t base; 5344 5345 AUDIOHD_REG_SET32(AUDIOHD_REG_INTCTL, 0); 5346 base = AUDIOHD_REG_SD_BASE; 5347 for (i = 0; i < statep->hda_streams_nums; i++) { 5348 AUDIOHD_REG_SET8(base + AUDIOHD_SDREG_OFFSET_STS, 5349 AUDIOHDR_SD_STS_INTRS); 5350 base += AUDIOHD_REG_SD_LEN; 5351 } 5352 AUDIOHD_REG_SET32(AUDIOHD_REG_INTSTS, (uint32_t)(-1)); 5353 5354 } /* audiohd_disable_intr() */ 5355 5356 5357 /* 5358 * audiohd_12bit_verb_to_codec() 5359 * 5360 * Description: 5361 * 5362 */ 5363 static int 5364 audiohd_12bit_verb_to_codec(audiohd_state_t *statep, uint8_t caddr, 5365 uint8_t wid, 5366 uint16_t cmd, uint8_t param) 5367 { 5368 uint32_t verb; 5369 uint16_t wptr; 5370 uint16_t rptr; 5371 5372 ASSERT((cmd & AUDIOHDC_12BIT_VERB_MASK) == 0); 5373 5374 wptr = AUDIOHD_REG_GET16(AUDIOHD_REG_CORBWP) & AUDIOHD_CMDIO_ENT_MASK; 5375 rptr = AUDIOHD_REG_GET16(AUDIOHD_REG_CORBRP) & AUDIOHD_CMDIO_ENT_MASK; 5376 5377 wptr++; 5378 wptr &= AUDIOHD_CMDIO_ENT_MASK; 5379 5380 /* overflow */ 5381 if (wptr == rptr) { 5382 return (AUDIO_FAILURE); 5383 } 5384 5385 verb = (caddr & 0x0f) << AUDIOHD_VERB_ADDR_OFF; 5386 verb |= wid << AUDIOHD_VERB_NID_OFF; 5387 verb |= cmd << AUDIOHD_VERB_CMD_OFF; 5388 verb |= param; 5389 5390 *((uint32_t *)(statep->hda_dma_corb.ad_vaddr) + wptr) = verb; 5391 (void) ddi_dma_sync(statep->hda_dma_corb.ad_dmahdl, 0, 5392 sizeof (sd_bdle_t) * AUDIOHD_BDLE_NUMS, DDI_DMA_SYNC_FORDEV); 5393 AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, wptr); 5394 5395 return (AUDIO_SUCCESS); 5396 5397 } /* audiohd_12bit_verb_to_codec() */ 5398 5399 /* 5400 * audiohd_4bit_verb_to_codec() 5401 * 5402 * Description: 5403 * 5404 */ 5405 static int 5406 audiohd_4bit_verb_to_codec(audiohd_state_t *statep, uint8_t caddr, 5407 uint8_t wid, 5408 uint32_t cmd, uint16_t param) 5409 { 5410 uint32_t verb; 5411 uint16_t wptr; 5412 uint16_t rptr; 5413 5414 ASSERT((cmd & AUDIOHDC_4BIT_VERB_MASK) == 0); 5415 5416 wptr = AUDIOHD_REG_GET16(AUDIOHD_REG_CORBWP) & AUDIOHD_CMDIO_ENT_MASK; 5417 rptr = AUDIOHD_REG_GET16(AUDIOHD_REG_CORBRP) & AUDIOHD_CMDIO_ENT_MASK; 5418 5419 wptr++; 5420 wptr &= AUDIOHD_CMDIO_ENT_MASK; 5421 5422 /* overflow */ 5423 if (wptr == rptr) { 5424 return (AUDIO_FAILURE); 5425 } 5426 5427 verb = (caddr & 0x0f) << AUDIOHD_VERB_ADDR_OFF; 5428 verb |= wid << AUDIOHD_VERB_NID_OFF; 5429 verb |= cmd << AUDIOHD_VERB_CMD16_OFF; 5430 verb |= param; 5431 5432 *((uint32_t *)(statep->hda_dma_corb.ad_vaddr) + wptr) = verb; 5433 AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, wptr); 5434 5435 return (AUDIO_SUCCESS); 5436 5437 } /* audiohd_4bit_verb_to_codec() */ 5438 5439 /* 5440 * audiohd_response_from_codec() 5441 * 5442 * Description: 5443 * 5444 */ 5445 static int 5446 audiohd_response_from_codec(audiohd_state_t *statep, uint32_t *resp, 5447 uint32_t *respex) 5448 { 5449 uint16_t wptr; 5450 uint16_t rptr; 5451 uint32_t *lp; 5452 5453 wptr = AUDIOHD_REG_GET16(AUDIOHD_REG_RIRBWP) & 0x00ff; 5454 rptr = statep->hda_rirb_rp; 5455 5456 if (rptr == wptr) { 5457 return (AUDIO_FAILURE); 5458 } 5459 5460 rptr++; 5461 rptr &= AUDIOHD_RING_MAX_SIZE; 5462 5463 lp = (uint32_t *)(statep->hda_dma_rirb.ad_vaddr) + (rptr << 1); 5464 *resp = *(lp); 5465 *respex = *(lp + 1); 5466 5467 statep->hda_rirb_rp = rptr; 5468 5469 return (AUDIO_SUCCESS); 5470 5471 } /* audiohd_response_from_codec() */ 5472 5473 5474 /* 5475 * audioha_codec_verb_get() 5476 */ 5477 static uint32_t 5478 audioha_codec_verb_get(void *arg, uint8_t caddr, uint8_t wid, 5479 uint16_t verb, 5480 uint8_t param) 5481 { 5482 audiohd_state_t *statep = (audiohd_state_t *)arg; 5483 uint32_t resp; 5484 uint32_t respex; 5485 int ret; 5486 int i; 5487 5488 ret = audiohd_12bit_verb_to_codec(statep, caddr, wid, verb, param); 5489 if (ret != AUDIO_SUCCESS) { 5490 return (uint32_t)(-1); 5491 } 5492 5493 /* 5494 * Empirical testing times. 50 times is enough for audiohd spec 1.0. 5495 * But we need to make it work for audiohd spec 0.9, which is just a 5496 * draft version and requires more time to wait. 5497 */ 5498 for (i = 0; i < 500; i++) { 5499 ret = audiohd_response_from_codec(statep, &resp, &respex); 5500 if (((respex & AUDIOHD_BDLE_RIRB_SDI) == caddr) && 5501 ((respex & AUDIOHD_BDLE_RIRB_UNSOLICIT) == 0) && 5502 (ret == AUDIO_SUCCESS)) 5503 break; 5504 /* Empirical testing time, which works well */ 5505 drv_usecwait(30); 5506 } 5507 5508 if (ret == AUDIO_SUCCESS) { 5509 return (resp); 5510 } 5511 5512 audio_dev_warn(statep->adev, "timeout when get " 5513 " response from codec: wid=%d, verb=0x%04x, param=0x%04x", 5514 wid, verb, param); 5515 5516 return ((uint32_t)(-1)); 5517 5518 } /* audioha_codec_verb_get() */ 5519 5520 5521 /* 5522 * audioha_codec_4bit_verb_get() 5523 */ 5524 static uint32_t 5525 audioha_codec_4bit_verb_get(void *arg, uint8_t caddr, uint8_t wid, 5526 uint16_t verb, uint16_t param) 5527 { 5528 audiohd_state_t *statep = (audiohd_state_t *)arg; 5529 uint32_t resp; 5530 uint32_t respex; 5531 int ret; 5532 int i; 5533 5534 ret = audiohd_4bit_verb_to_codec(statep, caddr, wid, verb, param); 5535 if (ret != AUDIO_SUCCESS) { 5536 return (uint32_t)(-1); 5537 } 5538 5539 for (i = 0; i < 500; i++) { 5540 ret = audiohd_response_from_codec(statep, &resp, &respex); 5541 if (((respex & AUDIOHD_BDLE_RIRB_SDI) == caddr) && 5542 ((respex & AUDIOHD_BDLE_RIRB_UNSOLICIT) == 0) && 5543 (ret == AUDIO_SUCCESS)) 5544 break; 5545 /* Empirical testing time, which works well */ 5546 drv_usecwait(30); 5547 } 5548 5549 if (ret == AUDIO_SUCCESS) { 5550 return (resp); 5551 } 5552 5553 audio_dev_warn(statep->adev, "timeout when get " 5554 " response from codec: wid=%d, verb=0x%04x, param=0x%04x", 5555 wid, verb, param); 5556 5557 return ((uint32_t)(-1)); 5558 5559 } /* audioha_codec_4bit_verb_get() */ 5560