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