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