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