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