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