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