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 "Unkown HD codec"); 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 /* work around for hp mini 1000 laptop */ 3534 if (codec->vid == AUDIOHD_CODECID_HP) 3535 mixer_allow = 0; 3536 /* search an exclusive mixer widget path. This is preferred */ 3537 audiohd_do_build_output_path(codec, mixer_allow, &mnum, 1, 0); 3538 3539 /* search a shared mixer widget path for the remained pins */ 3540 audiohd_do_build_output_path(codec, mixer_allow, &mnum, 0, 0); 3541 3542 /* search an exclusive widget path without mixer for the remained pin */ 3543 audiohd_do_build_output_path(codec, 0, &mnum, 1, 0); 3544 3545 /* search a shared widget path without mixer for the remained pin */ 3546 audiohd_do_build_output_path(codec, 0, &mnum, 0, 0); 3547 3548 } /* audiohd_build_output_path */ 3549 3550 /* 3551 * audiohd_build_output_amp 3552 * 3553 * Description: 3554 * Find the gain control and mute control widget 3555 */ 3556 static void 3557 audiohd_build_output_amp(hda_codec_t *codec) 3558 { 3559 audiohd_path_t *path; 3560 audiohd_widget_t *w, *widget, *wpin, *wdac; 3561 audiohd_pin_t *pin; 3562 wid_t wid; 3563 int weight; 3564 int i, j; 3565 uint32_t gain; 3566 3567 for (i = 0; i < codec->soft_statep->pathnum; i++) { 3568 path = codec->soft_statep->path[i]; 3569 if (path == NULL || path->path_type == RECORD || 3570 path->codec != codec) 3571 continue; 3572 for (j = 0; j < path->pin_nums; j++) { 3573 wid = path->pin_wid[j]; 3574 wpin = codec->widget[wid]; 3575 pin = (audiohd_pin_t *)wpin->priv; 3576 weight = wpin->out_weight; 3577 3578 /* 3579 * search a node which can mute this pin while 3580 * the mute functionality doesn't effect other 3581 * pins. 3582 */ 3583 widget = wpin; 3584 while (widget) { 3585 if (widget->outamp_cap & 3586 AUDIOHDC_AMP_CAP_MUTE_CAP) { 3587 pin->mute_wid = widget->wid_wid; 3588 pin->mute_dir = AUDIOHDC_AMP_SET_OUTPUT; 3589 break; 3590 } 3591 if (widget->inamp_cap & 3592 AUDIOHDC_AMP_CAP_MUTE_CAP) { 3593 pin->mute_wid = widget->wid_wid; 3594 pin->mute_dir = AUDIOHDC_AMP_SET_INPUT; 3595 break; 3596 } 3597 if (widget->selconn == AUDIOHD_NULL_CONN) 3598 break; 3599 wid = widget->avail_conn[widget->selconn]; 3600 widget = codec->widget[wid]; 3601 if (widget && widget->out_weight != weight) 3602 break; 3603 } 3604 3605 /* 3606 * We select the wid which has maxium gain range in 3607 * the output path. Meanwhile, the gain controlling 3608 * of this node doesn't effect other pins if this 3609 * output stream has multiple pins. 3610 */ 3611 gain = 0; 3612 widget = wpin; 3613 while (widget) { 3614 gain = (widget->outamp_cap & 3615 AUDIOHDC_AMP_CAP_STEP_NUMS); 3616 if (gain && gain > pin->gain_bits) { 3617 pin->gain_dir = AUDIOHDC_AMP_SET_OUTPUT; 3618 pin->gain_bits = gain; 3619 pin->gain_wid = widget->wid_wid; 3620 } 3621 gain = widget->inamp_cap & 3622 AUDIOHDC_AMP_CAP_STEP_NUMS; 3623 if (gain && gain > pin->gain_bits) { 3624 pin->gain_dir = AUDIOHDC_AMP_SET_INPUT; 3625 pin->gain_bits = gain; 3626 pin->gain_wid = widget->wid_wid; 3627 } 3628 if (widget->selconn == AUDIOHD_NULL_CONN) 3629 break; 3630 wid = widget->avail_conn[widget->selconn]; 3631 widget = codec->widget[wid]; 3632 if (widget && widget->out_weight != weight) 3633 break; 3634 } 3635 pin->gain_bits >>= AUDIOHD_GAIN_OFF; 3636 } 3637 3638 /* 3639 * if this stream has multiple pins, we try to find 3640 * a mute & gain-controlling nodes which can effect 3641 * all output pins of this stream to be used for the 3642 * whole stream 3643 */ 3644 if (path->pin_nums == 1) { 3645 path->mute_wid = pin->mute_wid; 3646 path->mute_dir = pin->mute_dir; 3647 path->gain_wid = pin->gain_wid; 3648 path->gain_dir = pin->gain_dir; 3649 path->gain_bits = pin->gain_bits; 3650 } else { 3651 wdac = codec->widget[path->adda_wid]; 3652 weight = wdac->out_weight; 3653 wid = path->pin_wid[0]; 3654 w = codec->widget[wid]; 3655 while (w && w->out_weight != weight) { 3656 wid = w->avail_conn[w->selconn]; 3657 w = codec->widget[wid]; 3658 } 3659 3660 /* find mute controlling node for this stream */ 3661 widget = w; 3662 while (widget) { 3663 if (widget->outamp_cap & 3664 AUDIOHDC_AMP_CAP_MUTE_CAP) { 3665 path->mute_wid = widget->wid_wid; 3666 path->mute_dir = 3667 AUDIOHDC_AMP_SET_OUTPUT; 3668 break; 3669 } 3670 if (widget->inamp_cap & 3671 AUDIOHDC_AMP_CAP_MUTE_CAP) { 3672 path->mute_wid = widget->wid_wid; 3673 path->mute_dir = 3674 AUDIOHDC_AMP_SET_INPUT; 3675 break; 3676 } 3677 if (widget->selconn == AUDIOHD_NULL_CONN) 3678 break; 3679 wid = widget->avail_conn[widget->selconn]; 3680 widget = codec->widget[wid]; 3681 } 3682 3683 /* find volume controlling node for this stream */ 3684 gain = 0; 3685 widget = w; 3686 while (widget) { 3687 gain = (widget->outamp_cap & 3688 AUDIOHDC_AMP_CAP_STEP_NUMS); 3689 if (gain && gain > pin->gain_bits) { 3690 path->gain_dir = 3691 AUDIOHDC_AMP_SET_OUTPUT; 3692 path->gain_bits = gain; 3693 path->gain_wid = widget->wid_wid; 3694 } 3695 gain = widget->inamp_cap & 3696 AUDIOHDC_AMP_CAP_STEP_NUMS; 3697 if (gain && (gain > pin->gain_bits) && 3698 (widget->type != WTYPE_AUDIO_MIX)) { 3699 path->gain_dir = 3700 AUDIOHDC_AMP_SET_INPUT; 3701 path->gain_bits = gain; 3702 path->gain_wid = widget->wid_wid; 3703 } 3704 if (widget->selconn == AUDIOHD_NULL_CONN) 3705 break; 3706 wid = widget->avail_conn[widget->selconn]; 3707 widget = codec->widget[wid]; 3708 } 3709 path->gain_bits >>= AUDIOHD_GAIN_OFF; 3710 } 3711 3712 } 3713 3714 } /* audiohd_build_output_amp */ 3715 3716 /* 3717 * audiohd_finish_output_path() 3718 * 3719 * Description: 3720 * Enable the widgets on the output path 3721 */ 3722 static void 3723 audiohd_finish_output_path(hda_codec_t *codec) 3724 { 3725 audiohd_state_t *statep = codec->soft_statep; 3726 audiohd_path_t *path; 3727 audiohd_widget_t *widget; 3728 audiohd_pin_t *pin; 3729 uint_t caddr = codec->index; 3730 wid_t wid; 3731 int i, j; 3732 3733 for (i = 0; i < codec->soft_statep->pathnum; i++) { 3734 path = codec->soft_statep->path[i]; 3735 if (!path || path->path_type != PLAY || path->codec != codec) 3736 continue; 3737 for (j = 0; j < path->pin_nums; j++) { 3738 wid = path->pin_wid[j]; 3739 widget = codec->widget[wid]; 3740 pin = (audiohd_pin_t *)widget->priv; 3741 { 3742 uint32_t lTmp; 3743 3744 lTmp = audioha_codec_verb_get(statep, caddr, wid, 3745 AUDIOHDC_VERB_GET_PIN_CTRL, 0); 3746 (void) audioha_codec_verb_get(statep, caddr, wid, 3747 AUDIOHDC_VERB_SET_PIN_CTRL, (lTmp | 3748 pin->vrefvalue | 3749 AUDIOHDC_PIN_CONTROL_OUT_ENABLE | 3750 AUDIOHDC_PIN_CONTROL_HP_ENABLE) & 3751 ~ AUDIOHDC_PIN_CONTROL_IN_ENABLE); 3752 } 3753 /* If this pin has external amplifier, enable it */ 3754 if (pin->cap & AUDIOHD_EXT_AMP_MASK) 3755 (void) audioha_codec_verb_get(statep, caddr, 3756 wid, AUDIOHDC_VERB_SET_EAPD, 3757 AUDIOHD_EXT_AMP_ENABLE); 3758 3759 if (widget->outamp_cap) { 3760 (void) audioha_codec_4bit_verb_get(statep, 3761 caddr, wid, AUDIOHDC_VERB_SET_AMP_MUTE, 3762 AUDIOHDC_AMP_SET_LR_OUTPUT | 3763 AUDIOHDC_GAIN_MAX); 3764 } 3765 3766 (void) audioha_codec_verb_get(statep, caddr, wid, 3767 AUDIOHDC_VERB_SET_CONN_SEL, widget->selconn); 3768 3769 wid = widget->avail_conn[widget->selconn]; 3770 widget = codec->widget[wid]; 3771 3772 while (widget) { 3773 /* 3774 * Set all amplifiers in this path to 3775 * the maximum 3776 * volume and unmute them. 3777 */ 3778 if (widget->outamp_cap) { 3779 (void) audioha_codec_4bit_verb_get( 3780 statep, 3781 caddr, 3782 wid, AUDIOHDC_VERB_SET_AMP_MUTE, 3783 AUDIOHDC_AMP_SET_LR_OUTPUT | 3784 AUDIOHDC_GAIN_MAX); 3785 } 3786 if (widget->inamp_cap) { 3787 (void) audioha_codec_4bit_verb_get( 3788 statep, 3789 caddr, 3790 wid, AUDIOHDC_VERB_SET_AMP_MUTE, 3791 AUDIOHDC_AMP_SET_LR_INPUT | 3792 AUDIOHDC_GAIN_MAX | 3793 (widget->selconn << 3794 AUDIOHDC_AMP_SET_INDEX_OFFSET)); 3795 } 3796 3797 if (widget->selconn == AUDIOHD_NULL_CONN) 3798 break; 3799 /* 3800 * Accoding to HD spec, mixer doesn't support 3801 * "select connection" 3802 */ 3803 if ((widget->type != WTYPE_AUDIO_MIX) && 3804 (widget->nconns > 1)) 3805 (void) audioha_codec_verb_get(statep, 3806 caddr, 3807 wid, 3808 AUDIOHDC_VERB_SET_CONN_SEL, 3809 widget->selconn); 3810 3811 wid = widget->avail_conn[widget->selconn]; 3812 widget = codec->widget[wid]; 3813 } 3814 } 3815 } 3816 } /* audiohd_finish_output_path() */ 3817 3818 /* 3819 * audiohd_find_input_pins() 3820 * 3821 * Description: 3822 * Here we consider a mixer/selector with multi-input as a real sum 3823 * widget. Only the first real mixer/selector widget is permitted in 3824 * an input path(recording path). If there are more mixers/selectors 3825 * execept the first one, only the first input/connection of those 3826 * widgets will be used by our driver, that means, we ignore other 3827 * inputs of those mixers/selectors. 3828 */ 3829 static int 3830 audiohd_find_input_pins(hda_codec_t *codec, wid_t wid, int allowmixer, 3831 int depth, audiohd_path_t *path) 3832 { 3833 audiohd_widget_t *widget = codec->widget[wid]; 3834 audiohd_pin_t *pin; 3835 audiohd_state_t *statep = codec->soft_statep; 3836 uint_t caddr = codec->index; 3837 int retval = -1; 3838 int num, i; 3839 uint32_t pinctrl; 3840 3841 if (depth > AUDIOHD_MAX_DEPTH) 3842 return (uint32_t)(DDI_FAILURE); 3843 if (widget == NULL) 3844 return (uint32_t)(DDI_FAILURE); 3845 3846 /* we don't share widgets */ 3847 if (widget->path_flags & AUDIOHD_PATH_ADC || 3848 widget->path_flags & AUDIOHD_PATH_DAC) 3849 return (uint32_t)(DDI_FAILURE); 3850 3851 switch (widget->type) { 3852 case WTYPE_PIN: 3853 pin = (audiohd_pin_t *)widget->priv; 3854 if (pin->no_phys_conn) 3855 return (uint32_t)(DDI_FAILURE); 3856 /* enable the pins' input capability */ 3857 pinctrl = audioha_codec_verb_get(statep, caddr, wid, 3858 AUDIOHDC_VERB_GET_PIN_CTRL, 0); 3859 (void) audioha_codec_verb_get(statep, caddr, wid, 3860 AUDIOHDC_VERB_SET_PIN_CTRL, 3861 pinctrl | AUDIOHD_PIN_IN_ENABLE); 3862 if (pin->cap & AUDIOHD_EXT_AMP_MASK) { 3863 (void) audioha_codec_verb_get(statep, caddr, 3864 wid, AUDIOHDC_VERB_SET_EAPD, 3865 AUDIOHD_EXT_AMP_ENABLE); 3866 } 3867 switch (pin->device) { 3868 case DTYPE_CD: 3869 case DTYPE_LINE_IN: 3870 case DTYPE_MIC_IN: 3871 case DTYPE_AUX: 3872 widget->path_flags |= AUDIOHD_PATH_ADC; 3873 widget->in_weight++; 3874 path->pin_wid[path->pin_nums++] = wid; 3875 pin->adc_dac_wid = path->adda_wid; 3876 return (DDI_SUCCESS); 3877 } 3878 break; 3879 case WTYPE_AUDIO_MIX: 3880 case WTYPE_AUDIO_SEL: 3881 /* 3882 * If the sum widget has only one input, we don't 3883 * consider it as a real sum widget. 3884 */ 3885 if (widget->nconns == 1) { 3886 widget->selconn = 0; 3887 retval = audiohd_find_input_pins(codec, 3888 widget->avail_conn[0], 3889 allowmixer, depth + 1, path); 3890 if (retval != DDI_FAILURE) { 3891 widget->path_flags |= AUDIOHD_PATH_ADC; 3892 widget->in_weight++; 3893 } 3894 break; 3895 } 3896 3897 if (allowmixer) { 3898 /* 3899 * This is a real sum widget, we will reject 3900 * other real sum widget when we find more in 3901 * the following path-searching. 3902 */ 3903 for (int i = 0; i < widget->nconns; i++) { 3904 retval = audiohd_find_input_pins(codec, 3905 widget->avail_conn[i], 0, depth + 1, 3906 path); 3907 if (retval != DDI_FAILURE) { 3908 widget->in_weight++; 3909 num = path->pin_nums - 1; 3910 path->sum_selconn[num] = i; 3911 path->sum_wid = wid; 3912 widget->path_flags |= 3913 AUDIOHD_PATH_ADC; 3914 if (widget->selconn == 3915 AUDIOHD_NULL_CONN) { 3916 widget->selconn = i; 3917 } 3918 } 3919 } 3920 3921 /* return SUCCESS if we found at least one input path */ 3922 if (path->pin_nums > 0) 3923 retval = DDI_SUCCESS; 3924 } else { 3925 /* 3926 * We had already found a real sum before this one since 3927 * allowmixer is 0. 3928 */ 3929 for (i = 0; i < widget->nconns; i++) { 3930 retval = audiohd_find_input_pins(codec, 3931 widget->avail_conn[i], 0, depth + 1, 3932 path); 3933 if (retval != DDI_FAILURE) { 3934 widget->selconn = i; 3935 widget->path_flags |= AUDIOHD_PATH_ADC; 3936 widget->in_weight++; 3937 break; 3938 } 3939 } 3940 } 3941 break; 3942 default: 3943 break; 3944 } 3945 3946 return (retval); 3947 } /* audiohd_find_input_pins */ 3948 3949 /* 3950 * audiohd_build_input_path() 3951 * 3952 * Description: 3953 * Find input path for the codec 3954 */ 3955 static void 3956 audiohd_build_input_path(hda_codec_t *codec) 3957 { 3958 audiohd_widget_t *widget; 3959 audiohd_path_t *path = NULL; 3960 wid_t wid; 3961 int i; 3962 int retval; 3963 uint8_t rtag = 0; 3964 audiohd_state_t *statep = codec->soft_statep; 3965 3966 for (wid = codec->first_wid; wid <= codec->last_wid; wid++) { 3967 3968 widget = codec->widget[wid]; 3969 3970 /* check if it is an ADC widget */ 3971 if (!widget || widget->type != WTYPE_AUDIO_IN) 3972 continue; 3973 3974 if (path == NULL) 3975 path = kmem_zalloc(sizeof (audiohd_path_t), 3976 KM_SLEEP); 3977 else 3978 bzero(path, sizeof (audiohd_port_t)); 3979 3980 path->adda_wid = wid; 3981 3982 /* 3983 * Is there any ADC widget which has more than one input ?? 3984 * I don't believe. Anyway, we carefully deal with this. But 3985 * if hardware vendors embed a selector in a ADC, we just use 3986 * the first available input, which has connection to input pin 3987 * widget. Because selector cannot perform mixer functionality, 3988 * and we just permit one selector or mixer in a recording path, 3989 * if we use the selector embedded in ADC,we cannot use possible 3990 * mixer during path searching. 3991 */ 3992 for (i = 0; i < widget->nconns; i++) { 3993 retval = audiohd_find_input_pins(codec, 3994 widget->avail_conn[i], 1, 0, path); 3995 if (retval == DDI_SUCCESS) { 3996 path->codec = codec; 3997 path->statep = statep; 3998 path->path_type = RECORD; 3999 path->tag = ++rtag; 4000 codec->nistream++; 4001 statep->path[statep->pathnum++] = path; 4002 widget->selconn = i; 4003 widget->priv = path; 4004 path = NULL; 4005 break; 4006 } 4007 } 4008 } 4009 if (path) 4010 kmem_free(path, sizeof (audiohd_path_t)); 4011 } /* audiohd_build_input_path */ 4012 4013 /* 4014 * audiohd_build_input_amp() 4015 * 4016 * Description: 4017 * Find gain and mute control widgets on the input path 4018 */ 4019 static void 4020 audiohd_build_input_amp(hda_codec_t *codec) 4021 { 4022 audiohd_path_t *path; 4023 audiohd_widget_t *wsum, *wadc, *w; 4024 audiohd_pin_t *pin; 4025 uint_t gain; 4026 wid_t wid; 4027 int i, j; 4028 int weight; 4029 4030 for (i = 0; i < codec->soft_statep->pathnum; i++) { 4031 path = codec->soft_statep->path[i]; 4032 if (path == NULL || path->path_type != RECORD || 4033 path->codec != codec) 4034 continue; 4035 4036 wid = path->adda_wid; 4037 wadc = path->codec->widget[wid]; 4038 weight = wadc->in_weight; 4039 4040 /* 4041 * Search node which has mute functionality for 4042 * the whole input path 4043 */ 4044 w = wadc; 4045 while (w) { 4046 if (w->outamp_cap & AUDIOHDC_AMP_CAP_MUTE_CAP) { 4047 path->mute_wid = w->wid_wid; 4048 path->mute_dir = AUDIOHDC_AMP_SET_OUTPUT; 4049 break; 4050 } 4051 if ((w->inamp_cap & AUDIOHDC_AMP_CAP_MUTE_CAP) && 4052 (w->wid_wid != path->sum_wid)) { 4053 path->mute_wid = w->wid_wid; 4054 path->mute_dir = AUDIOHDC_AMP_SET_INPUT; 4055 break; 4056 } 4057 4058 if (w->selconn == AUDIOHD_NULL_CONN) 4059 break; 4060 wid = w->avail_conn[w->selconn]; 4061 w = path->codec->widget[wid]; 4062 if (w && w->in_weight != weight) 4063 break; 4064 } 4065 4066 /* 4067 * Search a node for amplifier adjusting for the whole 4068 * input path 4069 */ 4070 w = wadc; 4071 gain = 0; 4072 while (w) { 4073 gain = (w->outamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS); 4074 if (gain && gain > path->gain_bits) { 4075 path->gain_dir = AUDIOHDC_AMP_SET_OUTPUT; 4076 path->gain_bits = gain; 4077 path->gain_wid = w->wid_wid; 4078 } 4079 gain = w->inamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS; 4080 if (gain && (gain > path->gain_bits) && 4081 (w->wid_wid != path->sum_wid)) { 4082 path->gain_dir = AUDIOHDC_AMP_SET_INPUT; 4083 path->gain_bits = gain; 4084 path->gain_wid = w->wid_wid; 4085 } 4086 if (w->selconn == AUDIOHD_NULL_CONN) 4087 break; 4088 wid = w->avail_conn[w->selconn]; 4089 w = path->codec->widget[wid]; 4090 } 4091 path->gain_bits >>= AUDIOHD_GAIN_OFF; 4092 4093 /* 4094 * If the input path has one pin only, the mute/amp 4095 * controlling is shared by the whole path and pin 4096 */ 4097 if (path->pin_nums == 1) { 4098 wid = path->pin_wid[0]; 4099 w = path->codec->widget[wid]; 4100 pin = (audiohd_pin_t *)w->priv; 4101 pin->gain_dir = path->gain_dir; 4102 pin->gain_bits = path->gain_bits; 4103 pin->gain_wid = path->gain_wid; 4104 pin->mute_wid = path->mute_wid; 4105 pin->mute_dir = path->mute_dir; 4106 continue; 4107 } 4108 4109 /* 4110 * For multi-pin device, there must be a selector 4111 * or mixer along the input path, and the sum_wid 4112 * is the widget's node id. 4113 */ 4114 wid = path->sum_wid; 4115 wsum = path->codec->widget[wid]; /* sum widget */ 4116 4117 for (j = 0; j < path->pin_nums; j++) { 4118 wid = path->pin_wid[j]; 4119 w = path->codec->widget[wid]; 4120 pin = (audiohd_pin_t *)w->priv; 4121 4122 /* find node for mute */ 4123 if (wsum->inamp_cap & AUDIOHDC_AMP_CAP_MUTE_CAP) { 4124 pin->mute_wid = wsum->wid_wid; 4125 pin->mute_dir = AUDIOHDC_AMP_SET_INPUT; 4126 } else { 4127 wid = wsum->avail_conn[path->sum_selconn[i]]; 4128 w = path->codec->widget[wid]; 4129 while (w) { 4130 if (w->outamp_cap & 4131 AUDIOHDC_AMP_CAP_MUTE_CAP) { 4132 pin->mute_wid = w->wid_wid; 4133 pin->mute_dir = 4134 AUDIOHDC_AMP_SET_OUTPUT; 4135 break; 4136 } 4137 if (w->inamp_cap & 4138 AUDIOHDC_AMP_CAP_MUTE_CAP) { 4139 pin->mute_wid = w->wid_wid; 4140 pin->mute_dir = 4141 AUDIOHDC_AMP_SET_INPUT; 4142 break; 4143 } 4144 4145 if (w->selconn == AUDIOHD_NULL_CONN) 4146 break; 4147 wid = w->avail_conn[w->selconn]; 4148 w = path->codec->widget[wid]; 4149 } 4150 } 4151 4152 /* find node for amp controlling */ 4153 gain = (wsum->inamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS); 4154 wid = wsum->avail_conn[path->sum_selconn[i]]; 4155 w = path->codec->widget[wid]; 4156 while (w) { 4157 gain = (w->outamp_cap & 4158 AUDIOHDC_AMP_CAP_STEP_NUMS); 4159 if (gain && gain > pin->gain_bits) { 4160 pin->gain_dir = AUDIOHDC_AMP_SET_OUTPUT; 4161 pin->gain_bits = gain; 4162 pin->gain_wid = w->wid_wid; 4163 } 4164 gain = w->inamp_cap & 4165 AUDIOHDC_AMP_CAP_STEP_NUMS; 4166 if (gain && (gain > pin->gain_bits)) { 4167 pin->gain_dir = AUDIOHDC_AMP_SET_INPUT; 4168 pin->gain_bits = gain; 4169 pin->gain_wid = w->wid_wid; 4170 } 4171 if (w->selconn == AUDIOHD_NULL_CONN) 4172 break; 4173 wid = w->avail_conn[w->selconn]; 4174 w = path->codec->widget[wid]; 4175 } 4176 pin->gain_bits >>= AUDIOHD_GAIN_OFF; 4177 } 4178 } 4179 } /* audiohd_build_input_amp() */ 4180 4181 /* 4182 * audiohd_finish_input_path() 4183 * 4184 * Description: 4185 * Enable the widgets on the input path 4186 */ 4187 static void 4188 audiohd_finish_input_path(hda_codec_t *codec) 4189 { 4190 audiohd_state_t *statep = codec->soft_statep; 4191 audiohd_path_t *path; 4192 audiohd_widget_t *w, *wsum; 4193 uint_t caddr = codec->index; 4194 wid_t wid; 4195 int i, j; 4196 4197 for (i = 0; i < codec->soft_statep->pathnum; i++) { 4198 path = codec->soft_statep->path[i]; 4199 if (path == NULL || path->path_type != RECORD || 4200 path->codec != codec) 4201 continue; 4202 wid = path->adda_wid; 4203 w = path->codec->widget[wid]; 4204 while (w && (w->wid_wid != path->sum_wid) && 4205 (w->type != WTYPE_PIN)) { 4206 if ((w->type == WTYPE_AUDIO_SEL) && (w->nconns > 1)) 4207 (void) audioha_codec_verb_get(statep, caddr, 4208 w->wid_wid, 4209 AUDIOHDC_VERB_SET_CONN_SEL, w->selconn); 4210 4211 if (w->outamp_cap) { 4212 (void) audioha_codec_4bit_verb_get(statep, 4213 caddr, 4214 w->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE, 4215 AUDIOHDC_AMP_SET_LR_OUTPUT | 4216 AUDIOHDC_GAIN_MAX); 4217 } 4218 4219 if (w->inamp_cap) { 4220 (void) audioha_codec_4bit_verb_get(statep, 4221 caddr, 4222 w->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE, 4223 AUDIOHDC_AMP_SET_LR_INPUT | 4224 AUDIOHDC_GAIN_MAX | 4225 (w->selconn << 4226 AUDIOHDC_AMP_SET_INDEX_OFFSET)); 4227 } 4228 4229 wid = w->avail_conn[w->selconn]; 4230 w = path->codec->widget[wid]; 4231 } 4232 4233 /* 4234 * After exiting from the above loop, the widget pointed 4235 * by w can be a pin widget or select/mixer widget. If it 4236 * is a pin widget, we already finish "select connection" 4237 * operation for the whole path. 4238 */ 4239 if (w && w->type == WTYPE_PIN) 4240 continue; 4241 4242 /* 4243 * deal with multi-pin input devices. 4244 */ 4245 wid = path->sum_wid; 4246 wsum = path->codec->widget[wid]; 4247 if (wsum == NULL) 4248 continue; 4249 if (wsum->outamp_cap) { 4250 (void) audioha_codec_4bit_verb_get(statep, 4251 caddr, 4252 wsum->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE, 4253 AUDIOHDC_AMP_SET_LR_OUTPUT | 4254 AUDIOHDC_GAIN_MAX); 4255 } 4256 4257 for (j = 0; j < path->pin_nums; j++) { 4258 if (wsum->inamp_cap) { 4259 (void) audioha_codec_4bit_verb_get(statep, 4260 caddr, 4261 wsum->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE, 4262 AUDIOHDC_AMP_SET_LR_INPUT | 4263 AUDIOHDC_GAIN_MAX | 4264 (path->sum_selconn[j] << 4265 AUDIOHDC_AMP_SET_INDEX_OFFSET)); 4266 } 4267 if (wsum->type == WTYPE_AUDIO_SEL) { 4268 (void) audioha_codec_verb_get(statep, caddr, 4269 wsum->wid_wid, 4270 AUDIOHDC_VERB_SET_CONN_SEL, 4271 path->sum_selconn[j]); 4272 } 4273 4274 wid = wsum->avail_conn[path->sum_selconn[j]]; 4275 w = path->codec->widget[wid]; 4276 while (w && w->type != WTYPE_PIN) { 4277 if ((w->type != WTYPE_AUDIO_MIX) && 4278 (w->nconns > 1)) 4279 (void) audioha_codec_verb_get(statep, 4280 caddr, w->wid_wid, 4281 AUDIOHDC_VERB_SET_CONN_SEL, 4282 w->selconn); 4283 4284 if (w->outamp_cap) { 4285 (void) audioha_codec_4bit_verb_get( 4286 statep, 4287 caddr, 4288 w->wid_wid, 4289 AUDIOHDC_VERB_SET_AMP_MUTE, 4290 AUDIOHDC_AMP_SET_LR_OUTPUT | 4291 AUDIOHDC_GAIN_MAX); 4292 } 4293 4294 if (w->inamp_cap) { 4295 (void) audioha_codec_4bit_verb_get( 4296 statep, 4297 caddr, 4298 w->wid_wid, 4299 AUDIOHDC_VERB_SET_AMP_MUTE, 4300 AUDIOHDC_AMP_SET_LR_INPUT | 4301 AUDIOHDC_GAIN_MAX | 4302 (w->selconn << 4303 AUDIOHDC_AMP_SET_INDEX_OFFSET)); 4304 } 4305 wid = w->avail_conn[w->selconn]; 4306 w = path->codec->widget[wid]; 4307 } 4308 } 4309 } /* end of istream loop */ 4310 } /* audiohd_finish_input_path */ 4311 4312 /* 4313 * audiohd_find_inpin_for_monitor() 4314 * 4315 * Description: 4316 * Find input pin for monitor path. 4317 * 4318 * Arguments: 4319 * hda_codec_t *codec where the monitor path exists 4320 * audiohd_ostream_t *ostream output ostream 4321 * wid_t id no. of widget being searched 4322 * int mixer share or not 4323 */ 4324 static int 4325 audiohd_find_inpin_for_monitor(hda_codec_t *codec, 4326 audiohd_path_t *path, wid_t id, int mixer) 4327 { 4328 wid_t wid; 4329 audiohd_widget_t *widget; 4330 audiohd_pin_t *pin; 4331 int i, find = 0; 4332 4333 wid = id; 4334 widget = codec->widget[wid]; 4335 if (widget == NULL) 4336 return (uint32_t)(DDI_FAILURE); 4337 4338 if (widget->type == WTYPE_PIN) { 4339 pin = (audiohd_pin_t *)widget->priv; 4340 if (pin->no_phys_conn) 4341 return (uint32_t)(DDI_FAILURE); 4342 switch (pin->device) { 4343 case DTYPE_SPDIF_IN: 4344 widget->path_flags |= AUDIOHD_PATH_MON; 4345 return (DDI_SUCCESS); 4346 case DTYPE_CD: 4347 widget->path_flags |= AUDIOHD_PATH_MON; 4348 return (DDI_SUCCESS); 4349 case DTYPE_LINE_IN: 4350 widget->path_flags |= AUDIOHD_PATH_MON; 4351 return (DDI_SUCCESS); 4352 case DTYPE_MIC_IN: 4353 widget->path_flags |= AUDIOHD_PATH_MON; 4354 return (DDI_SUCCESS); 4355 case DTYPE_AUX: 4356 widget->path_flags |= AUDIOHD_PATH_MON; 4357 return (DDI_SUCCESS); 4358 default: 4359 return (uint32_t)(DDI_FAILURE); 4360 } 4361 } 4362 /* the widget has been visited and can't be directed to input pin */ 4363 if (widget->path_flags & AUDIOHD_PATH_NOMON) { 4364 return (uint32_t)(DDI_FAILURE); 4365 } 4366 /* the widget has been used by the monitor path, and we can share it */ 4367 if (widget->path_flags & AUDIOHD_PATH_MON) { 4368 if (mixer) 4369 return (DDI_SUCCESS); 4370 else 4371 return (uint32_t)(DDI_FAILURE); 4372 } 4373 switch (widget->type) { 4374 case WTYPE_AUDIO_MIX: 4375 for (i = 0; i < widget->nconns; i++) { 4376 if (widget->selconn == i && widget->path_flags & 4377 AUDIOHD_PATH_DAC) 4378 continue; 4379 if (audiohd_find_inpin_for_monitor(codec, 4380 path, 4381 widget->avail_conn[i], mixer) == 4382 DDI_SUCCESS) { 4383 widget->selmon[widget->used++] = i; 4384 widget->path_flags |= AUDIOHD_PATH_MON; 4385 find = 1; 4386 } 4387 } 4388 break; 4389 case WTYPE_AUDIO_SEL: 4390 for (i = 0; i < widget->nconns; i++) { 4391 if (widget->selconn == i && widget->path_flags & 4392 AUDIOHD_PATH_DAC) 4393 continue; 4394 if (audiohd_find_inpin_for_monitor(codec, 4395 path, 4396 widget->avail_conn[i], 4397 mixer) == 4398 DDI_SUCCESS) { 4399 widget->selmon[0] = i; 4400 widget->path_flags |= AUDIOHD_PATH_MON; 4401 return (DDI_SUCCESS); 4402 } 4403 } 4404 default: 4405 break; 4406 } 4407 if (!find) { 4408 widget->path_flags |= AUDIOHD_PATH_NOMON; 4409 return (uint32_t)(DDI_FAILURE); 4410 } 4411 else 4412 return (DDI_SUCCESS); 4413 } /* audiohd_find_inpin_for_monitor */ 4414 4415 /* 4416 * audiohd_build_monitor_path() 4417 * 4418 * Description: 4419 * The functionality of mixer is to mix inputs, such as CD-IN, MIC, 4420 * Line-in, etc, with DAC outputs, so as to minitor what is being 4421 * recorded and implement "What you hear is what you get". However, 4422 * this functionality are really hardware-dependent: the inputs 4423 * must be directed to MIXER if they can be directed to ADC as 4424 * recording sources. 4425 */ 4426 static void 4427 audiohd_build_monitor_path(hda_codec_t *codec) 4428 { 4429 audiohd_path_t *path; 4430 audiohd_widget_t *widget; 4431 audiohd_state_t *statep = codec->soft_statep; 4432 wid_t wid; 4433 int i, j, k, l, find; 4434 int mixernum = 0; 4435 4436 for (i = 0; i < statep->pathnum; i++) { 4437 path = statep->path[i]; 4438 if (!path || path->codec != codec ||path->path_type != PLAY) 4439 continue; 4440 for (j = 0; j < path->pin_nums; j++) { 4441 wid = path->pin_wid[j]; 4442 widget = codec->widget[wid]; 4443 l = 0; 4444 while (widget) { 4445 while (widget && 4446 ((widget->type != WTYPE_AUDIO_MIX) || 4447 (widget->nconns < 2))) { 4448 if (widget->selconn == 4449 AUDIOHD_NULL_CONN) 4450 break; 4451 wid = 4452 widget->avail_conn[widget->selconn]; 4453 widget = codec->widget[wid]; 4454 } 4455 4456 /* 4457 * No mixer in this output path, we cannot build 4458 * mixer path for this path, skip it, 4459 * and continue 4460 * for next output path. 4461 */ 4462 if (widget == NULL || widget->selconn == 4463 AUDIOHD_NULL_CONN) { 4464 break; 4465 } 4466 mixernum++; 4467 for (k = 0; k < widget->nconns; k++) { 4468 4469 /* 4470 * this connection must be routined 4471 * to DAC instead of an input pin 4472 * widget, we needn't waste time for 4473 * it 4474 */ 4475 if (widget->selconn == k) 4476 continue; 4477 find = 0; 4478 if (audiohd_find_inpin_for_monitor( 4479 codec, 4480 path, 4481 widget->avail_conn[k], 0) == 4482 DDI_SUCCESS) { 4483 path->mon_wid[j][l] = wid; 4484 widget->selmon[widget->used++] = 4485 k; 4486 widget->path_flags |= 4487 AUDIOHD_PATH_MON; 4488 find = 1; 4489 } else if ( 4490 audiohd_find_inpin_for_monitor( 4491 codec, 4492 path, 4493 widget->avail_conn[k], 1) == 4494 DDI_SUCCESS) { 4495 path->mon_wid[j][l] = wid; 4496 widget->selmon[widget->used++] = 4497 k; 4498 widget->path_flags |= 4499 AUDIOHD_PATH_MON; 4500 find = 1; 4501 4502 } 4503 4504 } 4505 4506 /* 4507 * we needn't check widget->selconn here 4508 * since this 4509 * widget is a selector or mixer, it cannot 4510 * be NULL connection. 4511 */ 4512 if (!find) { 4513 path->mon_wid[i][l] = 0; 4514 widget->path_flags |= 4515 AUDIOHD_PATH_NOMON; 4516 } 4517 wid = widget->avail_conn[widget->selconn]; 4518 widget = codec->widget[wid]; 4519 l++; 4520 } 4521 path->maxmixer[j] = l; 4522 } 4523 4524 } 4525 if (mixernum == 0) 4526 statep->monitor_unsupported = B_TRUE; 4527 else 4528 statep->monitor_unsupported = B_FALSE; 4529 } /* audiohd_build_monitor_path */ 4530 4531 /* 4532 * audiohd_do_finish_monitor_path 4533 * 4534 * Description: 4535 * Enable the widgets on the monitor path 4536 */ 4537 static void 4538 audiohd_do_finish_monitor_path(hda_codec_t *codec, audiohd_widget_t *wgt) 4539 { 4540 uint_t caddr = codec->index; 4541 audiohd_widget_t *widget = wgt; 4542 audiohd_widget_t *w; 4543 audiohd_state_t *statep = codec->soft_statep; 4544 wid_t wid; 4545 int i; 4546 int share = 0; 4547 4548 if (!widget || widget->finish) 4549 return; 4550 if (widget->path_flags & AUDIOHD_PATH_ADC) 4551 share = 1; 4552 if ((widget->outamp_cap)&&!share) 4553 (void) audioha_codec_4bit_verb_get(statep, caddr, 4554 widget->wid_wid, 4555 AUDIOHDC_VERB_SET_AMP_MUTE, 4556 AUDIOHDC_AMP_SET_LR_OUTPUT 4557 | AUDIOHDC_GAIN_MAX); 4558 if ((widget->inamp_cap)&&!share) { 4559 for (i = 0; i < widget->used; i++) { 4560 (void) audioha_codec_4bit_verb_get(statep, caddr, 4561 widget->wid_wid, AUDIOHDC_VERB_SET_AMP_MUTE, 4562 AUDIOHDC_AMP_SET_LR_INPUT | 4563 AUDIOHDC_GAIN_MAX | 4564 (widget->selmon[i] << 4565 AUDIOHDC_AMP_SET_INDEX_OFFSET)); 4566 } 4567 } 4568 if ((widget->type == WTYPE_AUDIO_SEL) && (widget->nconns > 1) && 4569 !share) { 4570 (void) audioha_codec_verb_get(statep, caddr, 4571 widget->wid_wid, 4572 AUDIOHDC_VERB_SET_CONN_SEL, widget->selmon[0]); 4573 } 4574 widget->finish = 1; 4575 if (widget->used == 0) 4576 return; 4577 if (widget->used > 0) { 4578 for (i = 0; i < widget->used; i++) { 4579 wid = widget->avail_conn[widget->selmon[i]]; 4580 w = codec->widget[wid]; 4581 audiohd_do_finish_monitor_path(codec, w); 4582 } 4583 } 4584 } /* audiohd_do_finish_monitor_path */ 4585 4586 /* 4587 * audiohd_finish_monitor_path 4588 * 4589 * Description: 4590 * Enable the monitor path for every ostream path 4591 */ 4592 static void 4593 audiohd_finish_monitor_path(hda_codec_t *codec) 4594 { 4595 audiohd_path_t *path; 4596 audiohd_widget_t *widget; 4597 audiohd_state_t *statep = codec->soft_statep; 4598 wid_t wid; 4599 int i, j, k; 4600 4601 for (i = 0; i < statep->pathnum; i++) { 4602 path = statep->path[i]; 4603 if (!path || path->codec != codec || path->path_type != PLAY) 4604 continue; 4605 for (j = 0; j < path->pin_nums; j++) { 4606 for (k = 0; k < path->maxmixer[j]; k++) { 4607 wid = path->mon_wid[j][k]; 4608 if (wid == 0) { 4609 continue; 4610 } 4611 widget = codec->widget[wid]; 4612 audiohd_do_finish_monitor_path(codec, widget); 4613 } 4614 } 4615 } 4616 } /* audiohd_finish_monitor_path */ 4617 4618 /* 4619 * audiohd_do_build_monit_amp() 4620 * 4621 * Description: 4622 * Search for the gain control widget for the monitor path 4623 */ 4624 static void 4625 audiohd_do_build_monitor_amp(hda_codec_t *codec, audiohd_pin_t *pin, 4626 audiohd_widget_t *widget) 4627 { 4628 audiohd_widget_t *w = widget; 4629 uint32_t gain; 4630 int i; 4631 wid_t wid; 4632 4633 if (!w || 4634 (w->type == WTYPE_PIN) || 4635 !w->used || 4636 (pin->num == AUDIOHD_MAX_CONN) || 4637 (w->path_flags & AUDIOHD_PATH_ADC)) 4638 return; 4639 if (!(w->path_flags & AUDIOHD_PATH_DAC)) { 4640 gain = w->outamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS; 4641 if (gain) { 4642 pin->mg_dir[pin->num] = AUDIOHDC_AMP_SET_OUTPUT; 4643 pin->mg_gain[pin->num] = gain; 4644 pin->mg_wid[pin->num] = w->wid_wid; 4645 pin->mg_gain[pin->num] >>= AUDIOHD_GAIN_OFF; 4646 pin->num++; 4647 return; 4648 } 4649 gain = w->inamp_cap & AUDIOHDC_AMP_CAP_STEP_NUMS; 4650 if (gain) { 4651 pin->mg_dir[pin->num] = AUDIOHDC_AMP_SET_INPUT; 4652 pin->mg_gain[pin->num] = gain; 4653 pin->mg_wid[pin->num] = w->wid_wid; 4654 pin->mg_gain[pin->num] >>= AUDIOHD_GAIN_OFF; 4655 pin->num++; 4656 return; 4657 } 4658 } 4659 for (i = 0; i < w->used; i++) { 4660 wid = w->avail_conn[w->selmon[i]]; 4661 audiohd_do_build_monitor_amp(codec, pin, codec->widget[wid]); 4662 } 4663 4664 4665 } /* audiohd_do_build_monitor_amp() */ 4666 4667 /* 4668 * audiohd_build_monitor_amp() 4669 * 4670 * Description: 4671 * Search gain control widget for every ostream monitor 4672 */ 4673 static void 4674 audiohd_build_monitor_amp(hda_codec_t *codec) 4675 { 4676 audiohd_path_t *path; 4677 audiohd_widget_t *widget, *w; 4678 audiohd_state_t *statep = codec->soft_statep; 4679 audiohd_pin_t *pin; 4680 wid_t wid, id; 4681 int i, j, k; 4682 4683 for (i = 0; i < statep->pathnum; i++) { 4684 path = statep->path[i]; 4685 if (!path || path->codec != codec || path->path_type != PLAY) 4686 continue; 4687 for (j = 0; j < path->pin_nums; j++) { 4688 id = path->pin_wid[j]; 4689 w = codec->widget[id]; 4690 pin = (audiohd_pin_t *)(w->priv); 4691 for (k = 0; k < path->maxmixer[j]; k++) { 4692 wid = path->mon_wid[j][k]; 4693 if (!wid) 4694 continue; 4695 widget = codec->widget[wid]; 4696 audiohd_do_build_monitor_amp(codec, pin, 4697 widget); 4698 } 4699 } 4700 } 4701 } 4702 4703 /* 4704 * audiohd_find_beep() 4705 * Description: 4706 * Find a beep for a beep path. Then the play data can be sent to the out 4707 * put pin through the beep path. 4708 * 4709 * Arguments: 4710 * hda_codec_t *codec where the beep widget exists 4711 * wid_t wid the no. of a widget 4712 * int depth the depth of search 4713 * 4714 * Return: 4715 * 1) wid of Beep widget; 4716 * 2) 0 if no path 4717 */ 4718 static wid_t 4719 audiohd_find_beep(hda_codec_t *codec, wid_t wid, int depth) 4720 { 4721 audiohd_widget_t *widget = codec->widget[wid]; 4722 wid_t wbeep = (uint32_t)(DDI_FAILURE); 4723 wid_t retval; 4724 4725 if (depth > AUDIOHD_MAX_DEPTH) 4726 return (uint32_t)(DDI_FAILURE); 4727 4728 if (widget == NULL) 4729 return (uint32_t)(DDI_FAILURE); 4730 4731 switch (widget->type) { 4732 case WTYPE_BEEP: 4733 widget->path_flags |= AUDIOHD_PATH_BEEP; 4734 wbeep = widget->wid_wid; 4735 break; 4736 4737 case WTYPE_AUDIO_MIX: 4738 case WTYPE_AUDIO_SEL: 4739 for (int i = 0; i < widget->nconns; i++) { 4740 retval = audiohd_find_beep(codec, 4741 widget->avail_conn[i], depth + 1); 4742 if (retval != (uint32_t)DDI_FAILURE) { 4743 if (widget->selconn != AUDIOHD_NULL_CONN) 4744 continue; 4745 widget->selconn = i; 4746 wbeep = retval; 4747 widget->path_flags |= AUDIOHD_PATH_BEEP; 4748 return (wbeep); 4749 } 4750 } 4751 default: 4752 break; 4753 } 4754 4755 return (wbeep); 4756 } /* audiohd_find_beep() */ 4757 4758 /* 4759 * audiohd_build_beep_path() 4760 * 4761 * Description: 4762 * Search an beep path for each pin in the codec. 4763 * Arguments: 4764 * hda_codec_t *codec where the beep path exists 4765 */ 4766 static void 4767 audiohd_build_beep_path(hda_codec_t *codec) 4768 { 4769 audiohd_pin_t *pin; 4770 audiohd_widget_t *widget; 4771 audiohd_path_t *path; 4772 wid_t wid; 4773 audiohd_state_t *statep; 4774 int i; 4775 boolean_t beeppath = B_FALSE; 4776 4777 statep = codec->soft_statep; 4778 4779 for (pin = codec->first_pin; pin; pin = pin->next) { 4780 if ((pin->cap & AUDIOHD_PIN_CAP_MASK) == 0) 4781 continue; 4782 if ((pin->config & AUDIOHD_PIN_CONF_MASK) == 4783 AUDIOHD_PIN_NO_CONN) 4784 continue; 4785 if ((pin->device != DTYPE_LINEOUT) && 4786 (pin->device != DTYPE_SPEAKER) && 4787 (pin->device != DTYPE_SPDIF_OUT) && 4788 (pin->device != DTYPE_HP_OUT)) 4789 continue; 4790 widget = codec->widget[pin->wid]; 4791 4792 widget->inamp_cap = 0; 4793 for (i = 0; i < widget->nconns; i++) { 4794 /* 4795 * If a beep found, the return value is the wid of the 4796 * widget on the path, or the return value is 4797 * DDI_FAILURE 4798 */ 4799 wid = audiohd_find_beep(codec, 4800 widget->avail_conn[i], 0); 4801 /* 4802 * A beep was not found 4803 */ 4804 if (wid == (wid_t)DDI_FAILURE) 4805 continue; 4806 if (widget->selconn != AUDIOHD_NULL_CONN) 4807 continue; 4808 path = (audiohd_path_t *) 4809 kmem_zalloc(sizeof (audiohd_path_t), 4810 KM_SLEEP); 4811 path->beep_wid = wid; 4812 path->pin_wid[0] = widget->wid_wid; 4813 path->pin_nums = 1; 4814 path->path_type = BEEP; 4815 beeppath = 1; 4816 path->codec = codec; 4817 path->statep = statep; 4818 widget->path_flags |= AUDIOHD_PATH_BEEP; 4819 widget->selconn = i; 4820 statep->path[statep->pathnum++] = path; 4821 4822 break; 4823 } 4824 } 4825 4826 if (!beeppath) { 4827 for (int i = 0; i < AUDIOHD_CODEC_MAX; i++) { 4828 codec = statep->codec[i]; 4829 if (!codec) 4830 continue; 4831 for (wid = codec->first_wid; wid <= codec->last_wid; 4832 wid++) { 4833 widget = codec->widget[wid]; 4834 if (widget->type == WTYPE_BEEP) { 4835 path = (audiohd_path_t *) 4836 kmem_zalloc(sizeof (audiohd_path_t), 4837 KM_SLEEP); 4838 path->beep_wid = wid; 4839 path->pin_nums = 0; 4840 path->path_type = BEEP; 4841 beeppath = 1; 4842 path->codec = codec; 4843 path->statep = statep; 4844 widget->path_flags |= AUDIOHD_PATH_BEEP; 4845 statep->path[statep->pathnum++] = path; 4846 break; 4847 } 4848 } 4849 } 4850 } 4851 } /* audiohd_build_beep_path() */ 4852 4853 /* 4854 * audiohd_build_beep_amp 4855 * 4856 * Description: 4857 * Find the gain control and mute control widget 4858 */ 4859 static void 4860 audiohd_build_beep_amp(hda_codec_t *codec) 4861 { 4862 audiohd_path_t *path; 4863 audiohd_widget_t *widget, *wpin, *wbeep; 4864 wid_t wid; 4865 int i, j; 4866 uint32_t gain; 4867 4868 for (i = 0; i < codec->soft_statep->pathnum; i++) { 4869 path = codec->soft_statep->path[i]; 4870 if (path == NULL || path->path_type != BEEP || 4871 path->codec != codec) 4872 continue; 4873 if (path->pin_nums == 0) { 4874 path->mute_wid = path->beep_wid; 4875 path->mute_dir = AUDIOHDC_AMP_SET_OUTPUT; 4876 wbeep = codec->widget[path->beep_wid]; 4877 gain = (wbeep->outamp_cap & 4878 AUDIOHDC_AMP_CAP_STEP_NUMS); 4879 if (gain) { 4880 path->gain_dir = AUDIOHDC_AMP_SET_OUTPUT; 4881 path->gain_bits = gain; 4882 path->gain_wid = path->beep_wid; 4883 } 4884 path->gain_bits >>= AUDIOHD_GAIN_OFF; 4885 break; 4886 } 4887 for (j = 0; j < path->pin_nums; j++) { 4888 wid = path->pin_wid[j]; 4889 wpin = codec->widget[wid]; 4890 wbeep = codec->widget[path->beep_wid]; 4891 4892 widget = wpin; 4893 while (widget) { 4894 if (widget->out_weight == 0 && 4895 widget->outamp_cap & 4896 AUDIOHDC_AMP_CAP_MUTE_CAP) { 4897 path->mute_wid = widget->wid_wid; 4898 path->mute_dir = 4899 AUDIOHDC_AMP_SET_OUTPUT; 4900 break; 4901 } 4902 if (widget->selconn == AUDIOHD_NULL_CONN) 4903 break; 4904 wid = widget->avail_conn[widget->selconn]; 4905 widget = codec->widget[wid]; 4906 } 4907 4908 gain = 0; 4909 widget = wpin; 4910 while (widget) { 4911 if (widget->out_weight == 0 && 4912 widget->outamp_cap & 4913 AUDIOHDC_AMP_CAP_STEP_NUMS) { 4914 gain = (widget->outamp_cap & 4915 AUDIOHDC_AMP_CAP_STEP_NUMS); 4916 if (gain && gain > path->gain_bits) { 4917 path->gain_dir = 4918 AUDIOHDC_AMP_SET_OUTPUT; 4919 path->gain_bits = gain; 4920 path->gain_wid = 4921 widget->wid_wid; 4922 } 4923 } 4924 if (widget->selconn == AUDIOHD_NULL_CONN) 4925 break; 4926 wid = widget->avail_conn[widget->selconn]; 4927 widget = codec->widget[wid]; 4928 } 4929 path->gain_bits >>= AUDIOHD_GAIN_OFF; 4930 } 4931 } 4932 } /* audiohd_build_beep_amp */ 4933 4934 /* 4935 * audiohd_finish_beep_path() 4936 * 4937 * Description: 4938 * Enable the widgets on the beep path 4939 */ 4940 static void 4941 audiohd_finish_beep_path(hda_codec_t *codec) 4942 { 4943 audiohd_state_t *statep = codec->soft_statep; 4944 audiohd_path_t *path; 4945 audiohd_widget_t *widget; 4946 uint_t caddr = codec->index; 4947 wid_t wid; 4948 int i, j; 4949 4950 for (i = 0; i < codec->soft_statep->pathnum; i++) { 4951 path = codec->soft_statep->path[i]; 4952 if (!path || path->path_type != BEEP || path->codec != codec) 4953 continue; 4954 for (j = 0; j < path->pin_nums; j++) { 4955 wid = path->pin_wid[j]; 4956 widget = codec->widget[wid]; 4957 4958 (void) audioha_codec_verb_get(statep, caddr, wid, 4959 AUDIOHDC_VERB_SET_CONN_SEL, widget->selconn); 4960 4961 wid = widget->avail_conn[widget->selconn]; 4962 widget = codec->widget[wid]; 4963 4964 while (widget) { 4965 /* 4966 * Set all amplifiers in this path to 4967 * the maximum 4968 * volume and unmute them. 4969 */ 4970 if (widget->out_weight != 0) 4971 continue; 4972 if (widget->outamp_cap) { 4973 (void) audioha_codec_4bit_verb_get( 4974 statep, 4975 caddr, 4976 wid, AUDIOHDC_VERB_SET_AMP_MUTE, 4977 AUDIOHDC_AMP_SET_LR_OUTPUT | 4978 AUDIOHDC_GAIN_MAX); 4979 } 4980 if (widget->inamp_cap) { 4981 (void) audioha_codec_4bit_verb_get( 4982 statep, 4983 caddr, 4984 wid, AUDIOHDC_VERB_SET_AMP_MUTE, 4985 AUDIOHDC_AMP_SET_LR_INPUT | 4986 AUDIOHDC_GAIN_MAX | 4987 (widget->selconn << 4988 AUDIOHDC_AMP_SET_INDEX_OFFSET)); 4989 } 4990 4991 if (widget->selconn == AUDIOHD_NULL_CONN) 4992 break; 4993 /* 4994 * Accoding to HD spec, mixer doesn't support 4995 * "select connection" 4996 */ 4997 if ((widget->type != WTYPE_AUDIO_MIX) && 4998 (widget->nconns > 1)) 4999 (void) audioha_codec_verb_get(statep, 5000 caddr, 5001 wid, 5002 AUDIOHDC_VERB_SET_CONN_SEL, 5003 widget->selconn); 5004 5005 wid = widget->avail_conn[widget->selconn]; 5006 widget = codec->widget[wid]; 5007 } 5008 } 5009 } 5010 } /* audiohd_finish_beep_path */ 5011 5012 /* 5013 * audiohd_build_path() 5014 * 5015 * Description: 5016 * Here we build the output, input, monitor path. 5017 * And also enable the path in default. 5018 * Search for the gain and mute control for the path 5019 */ 5020 static void 5021 audiohd_build_path(audiohd_state_t *statep) 5022 { 5023 int i; 5024 5025 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 5026 if (statep->codec[i]) { 5027 audiohd_build_output_path(statep->codec[i]); 5028 audiohd_build_output_amp(statep->codec[i]); 5029 audiohd_finish_output_path(statep->codec[i]); 5030 5031 audiohd_build_input_path(statep->codec[i]); 5032 audiohd_build_input_amp(statep->codec[i]); 5033 audiohd_finish_input_path(statep->codec[i]); 5034 5035 audiohd_build_monitor_path(statep->codec[i]); 5036 audiohd_build_monitor_amp(statep->codec[i]); 5037 audiohd_finish_monitor_path(statep->codec[i]); 5038 5039 audiohd_build_beep_path(statep->codec[i]); 5040 audiohd_build_beep_amp(statep->codec[i]); 5041 audiohd_finish_beep_path(statep->codec[i]); 5042 } 5043 } 5044 } /* audiohd_build_path */ 5045 5046 /* 5047 * audiohd_allocate_port() 5048 */ 5049 static int 5050 audiohd_allocate_port(audiohd_state_t *statep) 5051 { 5052 int i, j; 5053 audiohd_port_t *port; 5054 int dir; 5055 unsigned caps; 5056 char *prop; 5057 int rc; 5058 audio_dev_t *adev; 5059 dev_info_t *dip; 5060 ddi_dma_cookie_t cookie; 5061 uint_t count; 5062 uint64_t buf_phys_addr; 5063 sd_bdle_t *entry; 5064 uint16_t gcap; 5065 size_t real_size; 5066 5067 adev = statep->adev; 5068 dip = statep->hda_dip; 5069 5070 ddi_dma_attr_t dma_attr = { 5071 DMA_ATTR_V0, /* version */ 5072 0, /* addr_lo */ 5073 0xffffffffffffffffULL, /* addr_hi */ 5074 0x00000000ffffffffULL, /* count_max */ 5075 128, /* 128-byte alignment as HD spec */ 5076 0xfff, /* burstsize */ 5077 1, /* minxfer */ 5078 0xffffffff, /* maxxfer */ 5079 0xffffffff, /* seg */ 5080 1, /* sgllen */ 5081 1, /* granular */ 5082 0 /* flags */ 5083 }; 5084 5085 gcap = AUDIOHD_REG_GET16(AUDIOHD_REG_GCAP); 5086 if ((gcap & AUDIOHDR_GCAP_64OK) == 0) 5087 dma_attr.dma_attr_addr_hi = 0xffffffffUL; 5088 5089 for (i = 0; i < PORT_MAX; i++) { 5090 port = kmem_zalloc(sizeof (*port), KM_SLEEP); 5091 port->started = B_FALSE; 5092 port->triggered = B_FALSE; 5093 statep->port[i] = port; 5094 port->statep = statep; 5095 switch (i) { 5096 case PORT_ADC: 5097 prop = "record-interrupts"; 5098 dir = DDI_DMA_READ | DDI_DMA_CONSISTENT; 5099 caps = ENGINE_INPUT_CAP; 5100 port->sync_dir = DDI_DMA_SYNC_FORKERNEL; 5101 port->nchan = statep->rchan; 5102 port->index = 1; 5103 port->regoff = AUDIOHD_REG_SD_BASE; 5104 break; 5105 case PORT_DAC: 5106 prop = "play-interrupts"; 5107 dir = DDI_DMA_WRITE | DDI_DMA_CONSISTENT; 5108 caps = ENGINE_OUTPUT_CAP; 5109 port->sync_dir = DDI_DMA_SYNC_FORDEV; 5110 port->nchan = statep->pchan; 5111 port->index = statep->hda_input_streams + 1; 5112 port->regoff = AUDIOHD_REG_SD_BASE + 5113 AUDIOHD_REG_SD_LEN * 5114 statep->hda_input_streams; 5115 break; 5116 default: 5117 return (DDI_FAILURE); 5118 } 5119 5120 port->intrs = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 5121 DDI_PROP_DONTPASS, prop, AUDIOHD_INTS); 5122 5123 /* make sure the values are good */ 5124 if (port->intrs < AUDIOHD_MIN_INTS) { 5125 audio_dev_warn(adev, "%s too low, %d, resetting to %d", 5126 prop, port->intrs, AUDIOHD_INTS); 5127 port->intrs = AUDIOHD_INTS; 5128 } else if (port->intrs > AUDIOHD_MAX_INTS) { 5129 audio_dev_warn(adev, "%s too high, %d, resetting to %d", 5130 prop, port->intrs, AUDIOHD_INTS); 5131 port->intrs = AUDIOHD_INTS; 5132 } 5133 5134 port->format = AUDIOHD_FMT_PCM; 5135 port->fragfr = 48000 / port->intrs; 5136 port->fragfr = (port->fragfr + AUDIOHD_FRAGFR_ALIGN - 1) & ~ 5137 (AUDIOHD_FRAGFR_ALIGN - 1); 5138 port->samp_size = port->fragfr * port->nchan * 2; 5139 port->samp_size = (port->samp_size + 5140 AUDIOHD_BDLE_BUF_ALIGN - 1) & ~ 5141 (AUDIOHD_BDLE_BUF_ALIGN - 1); 5142 5143 /* allocate dma handle */ 5144 rc = ddi_dma_alloc_handle(dip, &dma_attr, DDI_DMA_SLEEP, 5145 NULL, &port->samp_dmah); 5146 if (rc != DDI_SUCCESS) { 5147 audio_dev_warn(adev, "ddi_dma_alloc_handle failed: %d", 5148 rc); 5149 return (DDI_FAILURE); 5150 } 5151 /* allocate DMA buffer */ 5152 rc = ddi_dma_mem_alloc(port->samp_dmah, port->samp_size * 5153 AUDIOHD_BDLE_NUMS, 5154 &hda_dev_accattr, 5155 DDI_DMA_CONSISTENT, 5156 DDI_DMA_SLEEP, NULL, &port->samp_kaddr, 5157 &real_size, &port->samp_acch); 5158 if (rc == DDI_FAILURE) { 5159 audio_dev_warn(adev, "dma_mem_alloc failed"); 5160 return (DDI_FAILURE); 5161 } 5162 5163 /* bind DMA buffer */ 5164 rc = ddi_dma_addr_bind_handle(port->samp_dmah, NULL, 5165 port->samp_kaddr, real_size, dir, 5166 DDI_DMA_SLEEP, NULL, &cookie, &count); 5167 if ((rc != DDI_DMA_MAPPED) || (count != 1)) { 5168 audio_dev_warn(adev, 5169 "ddi_dma_addr_bind_handle failed: %d", rc); 5170 return (DDI_FAILURE); 5171 } 5172 port->samp_paddr = (uint64_t)cookie.dmac_laddress; 5173 5174 /* 5175 * now, from here we allocate DMA 5176 * memory for buffer descriptor list. 5177 * we allocate adjacent DMA memory for all DMA engines. 5178 */ 5179 rc = ddi_dma_alloc_handle(dip, &dma_attr, DDI_DMA_SLEEP, 5180 NULL, &port->bdl_dmah); 5181 if (rc != DDI_SUCCESS) { 5182 audio_dev_warn(adev, 5183 "ddi_dma_alloc_handle(bdlist) failed"); 5184 return (DDI_FAILURE); 5185 } 5186 5187 /* 5188 * we allocate all buffer descriptors lists in continuous 5189 * dma memory. 5190 */ 5191 port->bdl_size = sizeof (sd_bdle_t) * AUDIOHD_BDLE_NUMS; 5192 rc = ddi_dma_mem_alloc(port->bdl_dmah, port->bdl_size, 5193 &hda_dev_accattr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, 5194 &port->bdl_kaddr, &real_size, &port->bdl_acch); 5195 if (rc != DDI_SUCCESS) { 5196 audio_dev_warn(adev, 5197 "ddi_dma_mem_alloc(bdlist) failed"); 5198 return (DDI_FAILURE); 5199 } 5200 5201 rc = ddi_dma_addr_bind_handle(port->bdl_dmah, NULL, 5202 port->bdl_kaddr, 5203 real_size, DDI_DMA_WRITE | DDI_DMA_CONSISTENT, 5204 DDI_DMA_SLEEP, 5205 NULL, &cookie, &count); 5206 if ((rc != DDI_DMA_MAPPED) || (count != 1)) { 5207 audio_dev_warn(adev, "addr_bind_handle failed"); 5208 return (DDI_FAILURE); 5209 } 5210 port->bdl_paddr = (uint64_t)cookie.dmac_laddress; 5211 5212 entry = (sd_bdle_t *)port->bdl_kaddr; 5213 buf_phys_addr = port->samp_paddr; 5214 5215 for (j = 0; j < AUDIOHD_BDLE_NUMS; j++) { 5216 entry->sbde_addr = buf_phys_addr; 5217 entry->sbde_len = port->samp_size; 5218 entry->sbde_ioc = 1; 5219 buf_phys_addr += port->samp_size; 5220 entry++; 5221 } 5222 (void) ddi_dma_sync(port->bdl_dmah, 0, sizeof (sd_bdle_t) * 5223 AUDIOHD_BDLE_NUMS, DDI_DMA_SYNC_FORDEV); 5224 port->curpos = 0; 5225 5226 port->engine = audio_engine_alloc(&audiohd_engine_ops, caps); 5227 if (port->engine == NULL) { 5228 return (DDI_FAILURE); 5229 } 5230 5231 audio_engine_set_private(port->engine, port); 5232 audio_dev_add_engine(adev, port->engine); 5233 } 5234 5235 return (DDI_SUCCESS); 5236 } 5237 5238 static void 5239 audiohd_free_port(audiohd_state_t *statep) 5240 { 5241 int i; 5242 audiohd_port_t *port; 5243 5244 if (statep == NULL) { 5245 return; 5246 } 5247 for (i = 0; i < PORT_MAX; i++) { 5248 port = statep->port[i]; 5249 if (port == NULL) 5250 continue; 5251 if (port->engine) { 5252 audio_dev_remove_engine(statep->adev, 5253 port->engine); 5254 audio_engine_free(port->engine); 5255 } 5256 if (port->samp_dmah) { 5257 (void) ddi_dma_unbind_handle(port->samp_dmah); 5258 } 5259 if (port->samp_acch) { 5260 ddi_dma_mem_free(&port->samp_acch); 5261 } 5262 if (port->samp_dmah) { 5263 ddi_dma_free_handle(&port->samp_dmah); 5264 } 5265 if (port->bdl_dmah) { 5266 (void) ddi_dma_unbind_handle(port->bdl_dmah); 5267 } 5268 if (port->bdl_acch) { 5269 ddi_dma_mem_free(&port->bdl_acch); 5270 } 5271 if (port->bdl_dmah) { 5272 ddi_dma_free_handle(&port->bdl_dmah); 5273 } 5274 5275 kmem_free(port, sizeof (audiohd_port_t)); 5276 } 5277 } 5278 5279 /* 5280 * audiohd_change_widget_power_state(audiohd_state_t *statep, int off) 5281 * Description: 5282 * This routine is used to change the widget power betwen D0 and D2. 5283 * D0 is fully on; D2 allows the lowest possible power consuming state 5284 * from which it can return to the fully on state: D0. 5285 */ 5286 static void 5287 audiohd_change_widget_power_state(audiohd_state_t *statep, int off) 5288 { 5289 int i; 5290 wid_t wid; 5291 hda_codec_t *codec; 5292 audiohd_widget_t *widget; 5293 5294 /* Change power to D2 */ 5295 if (off) { 5296 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 5297 codec = statep->codec[i]; 5298 if (!codec) 5299 continue; 5300 for (wid = codec->first_wid; wid <= codec->last_wid; 5301 wid++) { 5302 widget = codec->widget[wid]; 5303 if (widget->widget_cap & 5304 AUDIOHD_WIDCAP_PWRCTRL) { 5305 (void) audioha_codec_verb_get(statep, 5306 codec->index, wid, 5307 AUDIOHDC_VERB_SET_POWER_STATE, 5308 AUDIOHD_PW_D2); 5309 } 5310 } 5311 } 5312 /* Change power to D0 */ 5313 } else { 5314 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 5315 codec = statep->codec[i]; 5316 if (!codec) 5317 continue; 5318 for (wid = codec->first_wid; wid <= codec->last_wid; 5319 wid++) { 5320 widget = codec->widget[wid]; 5321 if (widget->widget_cap & 5322 AUDIOHD_WIDCAP_PWRCTRL) { 5323 (void) audioha_codec_verb_get(statep, 5324 codec->index, wid, 5325 AUDIOHDC_VERB_SET_POWER_STATE, 5326 AUDIOHD_PW_D0); 5327 } 5328 } 5329 } 5330 } 5331 } 5332 /* 5333 * audiohd_restore_path() 5334 * Description: 5335 * This routine is used to restore the path on the codec. 5336 */ 5337 static void 5338 audiohd_restore_path(audiohd_state_t *statep) 5339 { 5340 int i; 5341 hda_codec_t *codec; 5342 5343 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 5344 codec = statep->codec[i]; 5345 if (!codec) 5346 continue; 5347 audiohd_finish_output_path(statep->codec[i]); 5348 audiohd_finish_input_path(statep->codec[i]); 5349 audiohd_finish_monitor_path(statep->codec[i]); 5350 } 5351 } 5352 5353 /* 5354 * restore_play_and_record() 5355 */ 5356 static void 5357 audiohd_restore_play_and_record(audiohd_state_t *statep) 5358 { 5359 int i; 5360 audiohd_port_t *port; 5361 5362 mutex_enter(&statep->hda_mutex); 5363 for (i = 0; i < PORT_MAX; i++) { 5364 port = statep->port[i]; 5365 if (port == NULL) 5366 continue; 5367 if (port != NULL) 5368 audio_engine_reset(port->engine); 5369 if (port->triggered) { 5370 (void) audiohd_reset_port(port); 5371 audiohd_start_port(port); 5372 } else { 5373 audiohd_stop_port(port); 5374 5375 } 5376 } 5377 mutex_exit(&statep->hda_mutex); 5378 } 5379 /* 5380 * audiohd_reset_pins_ur_cap() 5381 * Description: 5382 * Enable the unsolicited response of the pins which have the unsolicited 5383 * response capability 5384 */ 5385 static void 5386 audiohd_reset_pins_ur_cap(audiohd_state_t *statep) 5387 { 5388 hda_codec_t *codec; 5389 audiohd_pin_t *pin; 5390 audiohd_widget_t *widget; 5391 uint32_t urctrl; 5392 int i; 5393 5394 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 5395 codec = statep->codec[i]; 5396 if (!codec) 5397 continue; 5398 pin = codec->first_pin; 5399 while (pin) { 5400 /* enable the unsolicited response of the pin */ 5401 widget = codec->widget[pin->wid]; 5402 if ((widget->widget_cap & 5403 (AUDIOHD_URCAP_MASK) && 5404 (pin->cap & AUDIOHD_DTCCAP_MASK)) && 5405 ((pin->device == DTYPE_LINEOUT) || 5406 (pin->device == DTYPE_SPDIF_OUT) || 5407 (pin->device == DTYPE_HP_OUT) || 5408 (pin->device == DTYPE_MIC_IN))) { 5409 urctrl = (uint8_t)(1 << 5410 (AUDIOHD_UR_ENABLE_OFF - 1)); 5411 urctrl |= (pin->wid & AUDIOHD_UR_TAG_MASK); 5412 (void) audioha_codec_verb_get(statep, 5413 codec->index, 5414 pin->wid, 5415 AUDIOHDC_VERB_SET_URCTRL, urctrl); 5416 } 5417 pin = pin->next; 5418 } 5419 } 5420 } 5421 static void 5422 audiohd_restore_codec_gpio(audiohd_state_t *statep) 5423 { 5424 int i; 5425 wid_t wid; 5426 hda_codec_t *codec; 5427 5428 for (i = 0; i < AUDIOHD_CODEC_MAX; i++) { 5429 codec = statep->codec[i]; 5430 if (codec == NULL) 5431 continue; 5432 wid = codec->wid_afg; 5433 5434 /* power-up audio function group */ 5435 (void) audioha_codec_verb_get(statep, i, wid, 5436 AUDIOHDC_VERB_SET_POWER_STATE, 0); 5437 /* work around for Sony VAIO laptop with specific codec */ 5438 if ((codec->vid != AUDIOHD_CODECID_SONY1) && 5439 (codec->vid != AUDIOHD_CODECID_SONY2)) { 5440 /* 5441 * GPIO controls which are laptop specific workarounds 5442 * and might be changed. Some laptops use GPIO, 5443 * so we need to enable and set the GPIO correctly. 5444 */ 5445 (void) audioha_codec_verb_get(statep, i, wid, 5446 AUDIOHDC_VERB_SET_GPIO_MASK, AUDIOHDC_GPIO_ENABLE); 5447 (void) audioha_codec_verb_get(statep, i, wid, 5448 AUDIOHDC_VERB_SET_GPIO_DIREC, AUDIOHDC_GPIO_DIRECT); 5449 (void) audioha_codec_verb_get(statep, i, wid, 5450 AUDIOHDC_VERB_SET_GPIO_STCK, 5451 AUDIOHDC_GPIO_DATA_CTRL); 5452 (void) audioha_codec_verb_get(statep, i, wid, 5453 AUDIOHDC_VERB_SET_GPIO_DATA, 5454 AUDIOHDC_GPIO_STCK_CTRL); 5455 } 5456 } 5457 } 5458 /* 5459 * audiohd_resume() 5460 */ 5461 static int 5462 audiohd_resume(audiohd_state_t *statep) 5463 { 5464 uint8_t rirbsts; 5465 5466 mutex_enter(&statep->hda_mutex); 5467 statep->suspended = B_FALSE; 5468 /* Restore the hda state */ 5469 if (audiohd_reinit_hda(statep) == DDI_FAILURE) { 5470 audio_dev_warn(statep->adev, 5471 "hda reinit failed"); 5472 mutex_exit(&statep->hda_mutex); 5473 return (DDI_SUCCESS); 5474 } 5475 /* reset to enable the capability of unsolicited response for pin */ 5476 audiohd_reset_pins_ur_cap(statep); 5477 /* Enable interrupt */ 5478 AUDIOHD_REG_SET32(AUDIOHD_REG_INTCTL, 5479 AUDIOHD_INTCTL_BIT_GIE | 5480 AUDIOHD_INTCTL_BIT_SIE); 5481 /* clear the unsolicited response interrupt */ 5482 rirbsts = AUDIOHD_REG_GET8(AUDIOHD_REG_RIRBSTS); 5483 AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBSTS, rirbsts); 5484 mutex_exit(&statep->hda_mutex); 5485 5486 audiohd_restore_play_and_record(statep); 5487 audiohd_configure_output(statep); 5488 audiohd_configure_input(statep); 5489 5490 /* set widget power to D0 */ 5491 audiohd_change_widget_power_state(statep, AUDIOHD_PW_ON); 5492 5493 return (DDI_SUCCESS); 5494 } /* audiohd_resume */ 5495 5496 /* 5497 * audiohd_suspend() 5498 */ 5499 static int 5500 audiohd_suspend(audiohd_state_t *statep) 5501 { 5502 mutex_enter(&statep->hda_mutex); 5503 statep->suspended = B_TRUE; 5504 5505 /* set widget power to D2 */ 5506 audiohd_change_widget_power_state(statep, AUDIOHD_PW_OFF); 5507 /* Disable h/w */ 5508 audiohd_disable_intr(statep); 5509 audiohd_stop_dma(statep); 5510 mutex_exit(&statep->hda_mutex); 5511 5512 return (DDI_SUCCESS); 5513 } /* audiohd_suspend */ 5514 5515 /* 5516 * audiohd_disable_pin() 5517 */ 5518 static int 5519 audiohd_disable_pin(audiohd_state_t *statep, int caddr, wid_t wid) 5520 { 5521 AUDIOHD_DISABLE_PIN_OUT(statep, caddr, wid); 5522 return (DDI_SUCCESS); 5523 } 5524 5525 /* 5526 * audiohd_enable_pin() 5527 */ 5528 static int 5529 audiohd_enable_pin(audiohd_state_t *statep, int caddr, wid_t wid) 5530 { 5531 AUDIOHD_ENABLE_PIN_OUT(statep, caddr, wid); 5532 return (DDI_SUCCESS); 5533 } 5534 /* 5535 * audiohd_change_speaker_state() 5536 */ 5537 static void 5538 audiohd_change_speaker_state(audiohd_state_t *statep, int on) 5539 { 5540 audiohd_path_t *path; 5541 audiohd_widget_t *widget; 5542 audiohd_pin_t *pin; 5543 int i, j; 5544 wid_t wid; 5545 5546 for (i = 0; i < statep->pathnum; i++) { 5547 path = statep->path[i]; 5548 if (!path || path->path_type != PLAY) 5549 continue; 5550 if (on) { 5551 for (j = 0; j < path->pin_nums; j++) { 5552 wid = path->pin_wid[j]; 5553 widget = path->codec->widget[wid]; 5554 pin = (audiohd_pin_t *)widget->priv; 5555 if (pin->device == DTYPE_SPEAKER) { 5556 (void) audiohd_enable_pin( 5557 statep, 5558 path->codec->index, 5559 pin->wid); 5560 } 5561 } 5562 5563 } else { 5564 for (j = 0; j < path->pin_nums; j++) { 5565 wid = path->pin_wid[j]; 5566 widget = path->codec->widget[wid]; 5567 pin = (audiohd_pin_t *)widget->priv; 5568 if (pin->device == DTYPE_SPEAKER) { 5569 (void) audiohd_disable_pin( 5570 statep, 5571 path->codec->index, 5572 pin->wid); 5573 } 5574 } 5575 } 5576 } 5577 } 5578 /* 5579 * audiohd_select_mic() 5580 * 5581 * Description: 5582 * This function is used for the recording path which has a selector 5583 * as the sumwidget. We select the external MIC if it is plugged into the 5584 * MIC jack, otherwise the internal integrated MIC is selected. 5585 */ 5586 static void 5587 audiohd_select_mic(audiohd_state_t *statep, uint8_t index, 5588 uint8_t id, int select) 5589 { 5590 hda_codec_t *codec; 5591 audiohd_path_t *path; 5592 audiohd_widget_t *widget, *sumwgt; 5593 audiohd_pin_t *pin; 5594 int i, j; 5595 wid_t wid; 5596 5597 codec = statep->codec[index]; 5598 if (codec == NULL) 5599 return; 5600 for (i = 0; i < statep->pathnum; i++) { 5601 path = statep->path[i]; 5602 if (path->codec != codec || path->path_type != RECORD) 5603 continue; 5604 sumwgt = codec->widget[path->sum_wid]; 5605 if (path && sumwgt && 5606 (sumwgt->type == WTYPE_AUDIO_SEL)) { 5607 for (j = 0; j < path->pin_nums; j++) { 5608 wid = path->pin_wid[j]; 5609 widget = codec->widget[wid]; 5610 if (widget == NULL) 5611 return; 5612 pin = (audiohd_pin_t *)widget->priv; 5613 if (select && 5614 pin->device == DTYPE_MIC_IN && 5615 pin->wid == id && 5616 (((pin->config >> 5617 AUDIOHD_PIN_CONTP_OFF) & 5618 AUDIOHD_PIN_CONTP_MASK) == 5619 AUDIOHD_PIN_CON_JACK)) { 5620 (void) audioha_codec_verb_get( 5621 statep, 5622 index, 5623 path->sum_wid, 5624 AUDIOHDC_VERB_SET_CONN_SEL, 5625 path->sum_selconn[j]); 5626 statep->port[PORT_ADC]->index = 5627 path->tag; 5628 return; 5629 } else if (!select && 5630 pin->device == DTYPE_MIC_IN && 5631 pin->wid == id && 5632 (((pin->config >> 5633 AUDIOHD_PIN_CONTP_OFF) & 5634 AUDIOHD_PIN_CONTP_MASK) == 5635 AUDIOHD_PIN_CON_JACK)) { 5636 (void) audioha_codec_verb_get( 5637 statep, 5638 index, 5639 path->sum_wid, 5640 AUDIOHDC_VERB_SET_CONN_SEL, 5641 path->sum_selconn[j]); 5642 statep->port[PORT_ADC]->index = 5643 path->tag; 5644 return; 5645 } 5646 } 5647 if (path == NULL) 5648 break; 5649 sumwgt = codec->widget[path->sum_wid]; 5650 } 5651 } 5652 /* 5653 * If the input istream > 1, we should set the record stream tag 5654 * respectively. All the input streams sharing one tag may make the 5655 * record sound distorted. 5656 */ 5657 if (codec->nistream > 1) { 5658 for (i = 0; i < statep->pathnum; i++) { 5659 path = statep->path[i]; 5660 if (!path || path->path_type != RECORD) 5661 continue; 5662 for (j = 0; j < path->pin_nums; j++) { 5663 wid = path->pin_wid[j]; 5664 widget = codec->widget[wid]; 5665 if (widget == NULL) 5666 return; 5667 pin = (audiohd_pin_t *)widget->priv; 5668 if (select && 5669 pin->device == DTYPE_MIC_IN && 5670 pin->wid == id && 5671 (((pin->config >> 5672 AUDIOHD_PIN_CONTP_OFF) & 5673 AUDIOHD_PIN_CONTP_MASK) == 5674 AUDIOHD_PIN_CON_JACK)) { 5675 statep->port[PORT_ADC]->index = 5676 path->tag; 5677 return; 5678 } else if (!select && 5679 pin->device == DTYPE_MIC_IN && 5680 (((pin->config >> 5681 AUDIOHD_PIN_CONTP_OFF) & 5682 AUDIOHD_PIN_CONTP_MASK) == 5683 AUDIOHD_PIN_CON_FIXED)) { 5684 statep->port[PORT_ADC]->index = 5685 path->tag; 5686 return; 5687 } 5688 } 5689 } 5690 } 5691 } 5692 /* 5693 * audiohd_pin_sense() 5694 * 5695 * Description 5696 * 5697 * When the earphone is plugged into the jack associtated with the pin 5698 * complex, we disable the built in speaker. When the earphone is plugged 5699 * out of the jack, we enable the built in speaker. 5700 */ 5701 static void 5702 audiohd_pin_sense(audiohd_state_t *statep, uint32_t resp, uint32_t respex) 5703 { 5704 uint8_t index; 5705 uint8_t id; 5706 uint32_t rs; 5707 audiohd_widget_t *widget; 5708 audiohd_pin_t *pin; 5709 hda_codec_t *codec; 5710 5711 index = respex & AUDIOHD_RIRB_CODEC_MASK; 5712 id = resp >> (AUDIOHD_RIRB_WID_OFF - 1); 5713 5714 codec = statep->codec[index]; 5715 if (codec == NULL) 5716 return; 5717 widget = codec->widget[id]; 5718 if (widget == NULL) 5719 return; 5720 5721 rs = audioha_codec_verb_get(statep, index, id, 5722 AUDIOHDC_VERB_GET_PIN_SENSE, 0); 5723 if (rs >> (AUDIOHD_PIN_PRES_OFF - 1) & 1) { 5724 /* A MIC is plugged in, we select the MIC as input */ 5725 if ((widget->type == WTYPE_PIN) && 5726 (pin = (audiohd_pin_t *)widget->priv) && 5727 (pin->device == DTYPE_MIC_IN)) { 5728 audiohd_select_mic(statep, index, id, 1); 5729 return; 5730 } 5731 /* output pin is plugged */ 5732 audiohd_change_speaker_state(statep, AUDIOHD_SP_OFF); 5733 } else { 5734 /* 5735 * A MIC is unplugged, we select the built in MIC 5736 * as input. 5737 */ 5738 if ((widget->type == WTYPE_PIN) && 5739 (pin = (audiohd_pin_t *)widget->priv) && 5740 (pin->device == DTYPE_MIC_IN)) { 5741 audiohd_select_mic(statep, index, id, 0); 5742 return; 5743 } 5744 /* output pin is unplugged */ 5745 audiohd_change_speaker_state(statep, AUDIOHD_SP_ON); 5746 } 5747 5748 } 5749 /* 5750 * audiohd_intr() 5751 * 5752 * Description 5753 * 5754 * 5755 * Arguments: 5756 * caddr_t arg Pointer to the interrupting device's state 5757 * structure 5758 * 5759 * Returns: 5760 * DDI_INTR_CLAIMED Interrupt claimed and processed 5761 * DDI_INTR_UNCLAIMED Interrupt not claimed, and thus ignored 5762 */ 5763 static uint_t 5764 audiohd_intr(caddr_t arg) 5765 { 5766 audiohd_state_t *statep = (audiohd_state_t *)arg; 5767 uint32_t status; 5768 uint32_t regbase; 5769 uint32_t resp, respex; 5770 uint8_t sdstatus, rirbsts; 5771 int i, ret; 5772 audio_engine_t *do_adc = NULL; 5773 audio_engine_t *do_dac = NULL; 5774 5775 5776 mutex_enter(&statep->hda_mutex); 5777 if (statep->suspended) { 5778 mutex_exit(&statep->hda_mutex); 5779 return (DDI_INTR_UNCLAIMED); 5780 } 5781 5782 status = AUDIOHD_REG_GET32(AUDIOHD_REG_INTSTS); 5783 if (status == 0) { 5784 mutex_exit(&statep->hda_mutex); 5785 return (DDI_INTR_UNCLAIMED); 5786 } 5787 AUDIOHD_REG_SET32(AUDIOHD_REG_INTSTS, status); 5788 5789 /* 5790 * unsolicited response from pins, maybe something plugged in or out 5791 * of the jack. 5792 */ 5793 if (status & AUDIOHD_CIS_MASK) { 5794 /* clear the unsolicited response interrupt */ 5795 rirbsts = AUDIOHD_REG_GET8(AUDIOHD_REG_RIRBSTS); 5796 AUDIOHD_REG_SET8(AUDIOHD_REG_RIRBSTS, rirbsts); 5797 /* 5798 * We have to wait and try several times to make sure the 5799 * unsolicited response is generated by our pins. 5800 * we need to make it work for audiohd spec 0.9, which is 5801 * just a draft version and requires more time to wait. 5802 */ 5803 for (i = 0; i < AUDIOHD_TEST_TIMES; i++) { 5804 ret = audiohd_response_from_codec(statep, &resp, 5805 &respex); 5806 if ((ret == DDI_SUCCESS) && 5807 (respex & AUDIOHD_RIRB_UR_MASK)) { 5808 /* 5809 * A pin may generate more than one ur rirb, 5810 * we only need handle one of them, and clear 5811 * the other ones 5812 */ 5813 statep->hda_rirb_rp = 5814 AUDIOHD_REG_GET16(AUDIOHD_REG_RIRBWP) & 5815 AUDIOHD_RIRB_WPMASK; 5816 break; 5817 } 5818 } 5819 if ((ret == DDI_SUCCESS) && 5820 (respex & AUDIOHD_RIRB_UR_MASK)) { 5821 audiohd_pin_sense(statep, resp, respex); 5822 } 5823 } 5824 5825 /* stream intr */ 5826 for (i = 0; i < statep->hda_streams_nums; i++) { 5827 if ((status & (1<<i)) == 0) 5828 continue; 5829 5830 regbase = AUDIOHD_REG_SD_BASE + AUDIOHD_REG_SD_LEN * i; 5831 sdstatus = AUDIOHD_REG_GET8(regbase + AUDIOHD_SDREG_OFFSET_STS); 5832 5833 /* clear intrs */ 5834 AUDIOHD_REG_SET8(regbase + AUDIOHD_SDREG_OFFSET_STS, sdstatus); 5835 if (i < statep->hda_input_streams) 5836 do_adc = statep->port[PORT_ADC]->engine; 5837 else 5838 do_dac = statep->port[PORT_DAC]->engine; 5839 } 5840 5841 /* update the kernel interrupt statistics */ 5842 if (statep->hda_ksp) { 5843 ((kstat_intr_t *) 5844 (statep->hda_ksp->ks_data))->intrs[KSTAT_INTR_HARD]++; 5845 } 5846 5847 mutex_exit(&statep->hda_mutex); 5848 5849 if (do_adc) 5850 audio_engine_produce(do_adc); 5851 if (do_dac) 5852 audio_engine_consume(do_dac); 5853 return (DDI_INTR_CLAIMED); 5854 } /* audiohd_intr() */ 5855 5856 /* 5857 * audiohd_disable_intr() 5858 * 5859 * Description: 5860 * Disable all possible interrupts. 5861 */ 5862 static void 5863 audiohd_disable_intr(audiohd_state_t *statep) 5864 { 5865 int i; 5866 uint32_t base; 5867 5868 AUDIOHD_REG_SET32(AUDIOHD_REG_INTCTL, 0); 5869 base = AUDIOHD_REG_SD_BASE; 5870 for (i = 0; i < statep->hda_streams_nums; i++) { 5871 AUDIOHD_REG_SET8(base + AUDIOHD_SDREG_OFFSET_STS, 5872 AUDIOHDR_SD_STS_INTRS); 5873 base += AUDIOHD_REG_SD_LEN; 5874 } 5875 AUDIOHD_REG_SET32(AUDIOHD_REG_INTSTS, (uint32_t)(-1)); 5876 5877 } /* audiohd_disable_intr() */ 5878 5879 5880 /* 5881 * audiohd_12bit_verb_to_codec() 5882 * 5883 * Description: 5884 * 5885 */ 5886 static int 5887 audiohd_12bit_verb_to_codec(audiohd_state_t *statep, uint8_t caddr, 5888 uint8_t wid, 5889 uint16_t cmd, uint8_t param) 5890 { 5891 uint32_t verb; 5892 uint16_t wptr; 5893 uint16_t rptr; 5894 5895 ASSERT((cmd & AUDIOHDC_12BIT_VERB_MASK) == 0); 5896 5897 wptr = AUDIOHD_REG_GET16(AUDIOHD_REG_CORBWP) & AUDIOHD_CMDIO_ENT_MASK; 5898 rptr = AUDIOHD_REG_GET16(AUDIOHD_REG_CORBRP) & AUDIOHD_CMDIO_ENT_MASK; 5899 5900 wptr++; 5901 wptr &= AUDIOHD_CMDIO_ENT_MASK; 5902 5903 /* overflow */ 5904 if (wptr == rptr) { 5905 return (DDI_FAILURE); 5906 } 5907 5908 verb = (caddr & 0x0f) << AUDIOHD_VERB_ADDR_OFF; 5909 verb |= wid << AUDIOHD_VERB_NID_OFF; 5910 verb |= cmd << AUDIOHD_VERB_CMD_OFF; 5911 verb |= param; 5912 5913 *((uint32_t *)(statep->hda_dma_corb.ad_vaddr) + wptr) = verb; 5914 (void) ddi_dma_sync(statep->hda_dma_corb.ad_dmahdl, 0, 5915 sizeof (sd_bdle_t) * AUDIOHD_BDLE_NUMS, DDI_DMA_SYNC_FORDEV); 5916 AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, wptr); 5917 5918 return (DDI_SUCCESS); 5919 5920 } /* audiohd_12bit_verb_to_codec() */ 5921 5922 /* 5923 * audiohd_4bit_verb_to_codec() 5924 * 5925 * Description: 5926 * 5927 */ 5928 static int 5929 audiohd_4bit_verb_to_codec(audiohd_state_t *statep, uint8_t caddr, 5930 uint8_t wid, 5931 uint32_t cmd, uint16_t param) 5932 { 5933 uint32_t verb; 5934 uint16_t wptr; 5935 uint16_t rptr; 5936 5937 ASSERT((cmd & AUDIOHDC_4BIT_VERB_MASK) == 0); 5938 5939 wptr = AUDIOHD_REG_GET16(AUDIOHD_REG_CORBWP) & AUDIOHD_CMDIO_ENT_MASK; 5940 rptr = AUDIOHD_REG_GET16(AUDIOHD_REG_CORBRP) & AUDIOHD_CMDIO_ENT_MASK; 5941 5942 wptr++; 5943 wptr &= AUDIOHD_CMDIO_ENT_MASK; 5944 5945 /* overflow */ 5946 if (wptr == rptr) { 5947 return (DDI_FAILURE); 5948 } 5949 5950 verb = (caddr & 0x0f) << AUDIOHD_VERB_ADDR_OFF; 5951 verb |= wid << AUDIOHD_VERB_NID_OFF; 5952 verb |= cmd << AUDIOHD_VERB_CMD16_OFF; 5953 verb |= param; 5954 5955 *((uint32_t *)(statep->hda_dma_corb.ad_vaddr) + wptr) = verb; 5956 AUDIOHD_REG_SET16(AUDIOHD_REG_CORBWP, wptr); 5957 5958 return (DDI_SUCCESS); 5959 5960 } /* audiohd_4bit_verb_to_codec() */ 5961 5962 /* 5963 * audiohd_response_from_codec() 5964 * 5965 * Description: 5966 * 5967 */ 5968 static int 5969 audiohd_response_from_codec(audiohd_state_t *statep, uint32_t *resp, 5970 uint32_t *respex) 5971 { 5972 uint16_t wptr; 5973 uint16_t rptr; 5974 uint32_t *lp; 5975 5976 wptr = AUDIOHD_REG_GET16(AUDIOHD_REG_RIRBWP) & 0x00ff; 5977 rptr = statep->hda_rirb_rp; 5978 5979 if (rptr == wptr) { 5980 return (DDI_FAILURE); 5981 } 5982 5983 rptr++; 5984 rptr &= AUDIOHD_RING_MAX_SIZE; 5985 5986 lp = (uint32_t *)(statep->hda_dma_rirb.ad_vaddr) + (rptr << 1); 5987 *resp = *(lp); 5988 *respex = *(lp + 1); 5989 5990 statep->hda_rirb_rp = rptr; 5991 5992 return (DDI_SUCCESS); 5993 5994 } /* audiohd_response_from_codec() */ 5995 5996 5997 /* 5998 * audioha_codec_verb_get() 5999 */ 6000 static uint32_t 6001 audioha_codec_verb_get(void *arg, uint8_t caddr, uint8_t wid, 6002 uint16_t verb, 6003 uint8_t param) 6004 { 6005 audiohd_state_t *statep = (audiohd_state_t *)arg; 6006 uint32_t resp; 6007 uint32_t respex; 6008 int ret; 6009 int i; 6010 6011 ret = audiohd_12bit_verb_to_codec(statep, caddr, wid, verb, param); 6012 if (ret != DDI_SUCCESS) { 6013 return (uint32_t)(-1); 6014 } 6015 6016 /* 6017 * Empirical testing times. 50 times is enough for audiohd spec 1.0. 6018 * But we need to make it work for audiohd spec 0.9, which is just a 6019 * draft version and requires more time to wait. 6020 */ 6021 for (i = 0; i < 500; i++) { 6022 ret = audiohd_response_from_codec(statep, &resp, &respex); 6023 if (((respex & AUDIOHD_BDLE_RIRB_SDI) == caddr) && 6024 ((respex & AUDIOHD_BDLE_RIRB_UNSOLICIT) == 0) && 6025 (ret == DDI_SUCCESS)) 6026 break; 6027 /* Empirical testing time, which works well */ 6028 drv_usecwait(30); 6029 } 6030 6031 if (ret == DDI_SUCCESS) { 6032 return (resp); 6033 } 6034 6035 audio_dev_warn(statep->adev, "timeout when get " 6036 " response from codec: wid=%d, verb=0x%04x, param=0x%04x", 6037 wid, verb, param); 6038 6039 return ((uint32_t)(-1)); 6040 6041 } /* audioha_codec_verb_get() */ 6042 6043 6044 /* 6045 * audioha_codec_4bit_verb_get() 6046 */ 6047 static uint32_t 6048 audioha_codec_4bit_verb_get(void *arg, uint8_t caddr, uint8_t wid, 6049 uint16_t verb, uint16_t param) 6050 { 6051 audiohd_state_t *statep = (audiohd_state_t *)arg; 6052 uint32_t resp; 6053 uint32_t respex; 6054 int ret; 6055 int i; 6056 6057 ret = audiohd_4bit_verb_to_codec(statep, caddr, wid, verb, param); 6058 if (ret != DDI_SUCCESS) { 6059 return (uint32_t)(-1); 6060 } 6061 6062 for (i = 0; i < 500; i++) { 6063 ret = audiohd_response_from_codec(statep, &resp, &respex); 6064 if (((respex & AUDIOHD_BDLE_RIRB_SDI) == caddr) && 6065 ((respex & AUDIOHD_BDLE_RIRB_UNSOLICIT) == 0) && 6066 (ret == DDI_SUCCESS)) 6067 break; 6068 /* Empirical testing time, which works well */ 6069 drv_usecwait(30); 6070 } 6071 6072 if (ret == DDI_SUCCESS) { 6073 return (resp); 6074 } 6075 6076 audio_dev_warn(statep->adev, "timeout when get " 6077 " response from codec: wid=%d, verb=0x%04x, param=0x%04x", 6078 wid, verb, param); 6079 6080 return ((uint32_t)(-1)); 6081 6082 } /* audioha_codec_4bit_verb_get() */ 6083