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