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