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