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