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