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