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