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