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 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 /* 28 * audiocs Audio Driver 29 * 30 * This Audio Driver controls the Crystal CS4231 Codec used on many SPARC 31 * platforms. It does not support the CS4231 on Power PCs or x86 PCs. It 32 * does support two different DMA engines, the APC and EB2. The code for 33 * those DMA engines is split out and a well defined, but private, interface 34 * is used to control those DMA engines. 35 * 36 * For some reason setting the CS4231's registers doesn't always 37 * succeed. Therefore every time we set a register we always read it 38 * back to make sure it was set. If not we wait a little while and 39 * then try again. This is all taken care of in the routines 40 * audiocs_put_index() and audiocs_sel_index() and the macros ORIDX() 41 * and ANDIDX(). We don't worry about the status register because it 42 * is cleared by writing anything to it. So it doesn't matter what 43 * the value written is. 44 * 45 * This driver supports suspending and resuming. A suspend just stops playing 46 * and recording. The play DMA buffers end up getting thrown away, but when 47 * you shut down the machine there is a break in the audio anyway, so they 48 * won't be missed and it isn't worth the effort to save them. When we resume 49 * we always start playing and recording. If they aren't needed they get 50 * shut off by the mixer. 51 * 52 * Power management is supported by this driver. 53 * 54 * NOTE: This module depends on drv/audio being loaded first. 55 */ 56 57 #include <sys/modctl.h> 58 #include <sys/kmem.h> 59 #include <sys/stropts.h> 60 #include <sys/ddi.h> 61 #include <sys/sunddi.h> 62 #include <sys/note.h> 63 #include <sys/audio/audio_driver.h> 64 #include "audio_4231.h" 65 66 /* 67 * Module linkage routines for the kernel 68 */ 69 static int audiocs_ddi_attach(dev_info_t *, ddi_attach_cmd_t); 70 static int audiocs_ddi_detach(dev_info_t *, ddi_detach_cmd_t); 71 static int audiocs_ddi_power(dev_info_t *, int, int); 72 73 /* 74 * Entry point routine prototypes 75 */ 76 static int audiocs_open(void *, int, unsigned *, caddr_t *); 77 static void audiocs_close(void *); 78 static int audiocs_start(void *); 79 static void audiocs_stop(void *); 80 static int audiocs_format(void *); 81 static int audiocs_channels(void *); 82 static int audiocs_rate(void *); 83 static uint64_t audiocs_count(void *); 84 static void audiocs_sync(void *, unsigned); 85 86 /* 87 * Control callbacks. 88 */ 89 static int audiocs_get_value(void *, uint64_t *); 90 static int audiocs_set_ogain(void *, uint64_t); 91 static int audiocs_set_igain(void *, uint64_t); 92 static int audiocs_set_mgain(void *, uint64_t); 93 static int audiocs_set_inputs(void *, uint64_t); 94 static int audiocs_set_outputs(void *, uint64_t); 95 static int audiocs_set_micboost(void *, uint64_t); 96 97 /* Local Routines */ 98 static int audiocs_resume(dev_info_t *); 99 static int audiocs_attach(dev_info_t *); 100 static int audiocs_detach(dev_info_t *); 101 static int audiocs_suspend(dev_info_t *); 102 103 static void audiocs_destroy(CS_state_t *); 104 static int audiocs_init_state(CS_state_t *); 105 static int audiocs_chip_init(CS_state_t *); 106 static int audiocs_alloc_engine(CS_state_t *, int); 107 static void audiocs_free_engine(CS_engine_t *); 108 static void audiocs_get_ports(CS_state_t *); 109 static void audiocs_configure_input(CS_state_t *); 110 static void audiocs_configure_output(CS_state_t *); 111 static CS_ctrl_t *audiocs_alloc_ctrl(CS_state_t *, uint32_t, uint64_t); 112 static void audiocs_free_ctrl(CS_ctrl_t *); 113 static int audiocs_add_controls(CS_state_t *); 114 static void audiocs_del_controls(CS_state_t *); 115 static void audiocs_power_up(CS_state_t *); 116 static void audiocs_power_down(CS_state_t *); 117 static int audiocs_poll_ready(CS_state_t *); 118 #ifdef DEBUG 119 static void audiocs_put_index(CS_state_t *, uint8_t, uint8_t, int); 120 static void audiocs_sel_index(CS_state_t *, uint8_t, int); 121 #define SELIDX(s, idx) audiocs_sel_index(s, idx, __LINE__) 122 #define PUTIDX(s, val, mask) audiocs_put_index(s, val, mask, __LINE__) 123 #else 124 static void audiocs_put_index(CS_state_t *, uint8_t, uint8_t); 125 static void audiocs_sel_index(CS_state_t *, uint8_t); 126 #define SELIDX(s, idx) audiocs_sel_index(s, idx) 127 #define PUTIDX(s, val, mask) audiocs_put_index(s, val, mask) 128 #endif 129 #define GETIDX(s) ddi_get8((handle), &CS4231_IDR) 130 131 #define ORIDX(s, val, mask) \ 132 PUTIDX(s, \ 133 (ddi_get8((handle), &CS4231_IDR) | (uint8_t)(val)), \ 134 (uint8_t)(mask)) 135 136 #define ANDIDX(s, val, mask) \ 137 PUTIDX(s, (ddi_get8((handle), &CS4231_IDR) & (uint8_t)(val)), \ 138 (uint8_t)(mask)) 139 140 static audio_engine_ops_t audiocs_engine_ops = { 141 AUDIO_ENGINE_VERSION, 142 audiocs_open, 143 audiocs_close, 144 audiocs_start, 145 audiocs_stop, 146 audiocs_count, 147 audiocs_format, 148 audiocs_channels, 149 audiocs_rate, 150 audiocs_sync, 151 NULL, 152 NULL, 153 NULL, 154 }; 155 156 #define OUTPUT_SPEAKER 0 157 #define OUTPUT_HEADPHONES 1 158 #define OUTPUT_LINEOUT 2 159 160 static const char *audiocs_outputs[] = { 161 AUDIO_PORT_SPEAKER, 162 AUDIO_PORT_HEADPHONES, 163 AUDIO_PORT_LINEOUT, 164 NULL 165 }; 166 167 #define INPUT_MIC 0 168 #define INPUT_LINEIN 1 169 #define INPUT_STEREOMIX 2 170 #define INPUT_CD 3 171 172 static const char *audiocs_inputs[] = { 173 AUDIO_PORT_MIC, 174 AUDIO_PORT_LINEIN, 175 AUDIO_PORT_STEREOMIX, 176 AUDIO_PORT_CD, 177 NULL 178 }; 179 180 /* 181 * Global variables, but viewable only by this file. 182 */ 183 184 /* play gain array, converts linear gain to 64 steps of log10 gain */ 185 static uint8_t cs4231_atten[] = { 186 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, /* [000] -> [004] */ 187 0x3a, 0x39, 0x38, 0x37, 0x36, /* [005] -> [009] */ 188 0x35, 0x34, 0x33, 0x32, 0x31, /* [010] -> [014] */ 189 0x30, 0x2f, 0x2e, 0x2d, 0x2c, /* [015] -> [019] */ 190 0x2b, 0x2a, 0x29, 0x29, 0x28, /* [020] -> [024] */ 191 0x28, 0x27, 0x27, 0x26, 0x26, /* [025] -> [029] */ 192 0x25, 0x25, 0x24, 0x24, 0x23, /* [030] -> [034] */ 193 0x23, 0x22, 0x22, 0x21, 0x21, /* [035] -> [039] */ 194 0x20, 0x20, 0x1f, 0x1f, 0x1f, /* [040] -> [044] */ 195 0x1e, 0x1e, 0x1e, 0x1d, 0x1d, /* [045] -> [049] */ 196 0x1d, 0x1c, 0x1c, 0x1c, 0x1b, /* [050] -> [054] */ 197 0x1b, 0x1b, 0x1a, 0x1a, 0x1a, /* [055] -> [059] */ 198 0x1a, 0x19, 0x19, 0x19, 0x19, /* [060] -> [064] */ 199 0x18, 0x18, 0x18, 0x18, 0x17, /* [065] -> [069] */ 200 0x17, 0x17, 0x17, 0x16, 0x16, /* [070] -> [074] */ 201 0x16, 0x16, 0x16, 0x15, 0x15, /* [075] -> [079] */ 202 0x15, 0x15, 0x15, 0x14, 0x14, /* [080] -> [084] */ 203 0x14, 0x14, 0x14, 0x13, 0x13, /* [085] -> [089] */ 204 0x13, 0x13, 0x13, 0x12, 0x12, /* [090] -> [094] */ 205 0x12, 0x12, 0x12, 0x12, 0x11, /* [095] -> [099] */ 206 0x11, 0x11, 0x11, 0x11, 0x11, /* [100] -> [104] */ 207 0x10, 0x10, 0x10, 0x10, 0x10, /* [105] -> [109] */ 208 0x10, 0x0f, 0x0f, 0x0f, 0x0f, /* [110] -> [114] */ 209 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, /* [114] -> [119] */ 210 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, /* [120] -> [124] */ 211 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, /* [125] -> [129] */ 212 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, /* [130] -> [134] */ 213 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, /* [135] -> [139] */ 214 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, /* [140] -> [144] */ 215 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, /* [145] -> [149] */ 216 0x0a, 0x0a, 0x0a, 0x0a, 0x09, /* [150] -> [154] */ 217 0x09, 0x09, 0x09, 0x09, 0x09, /* [155] -> [159] */ 218 0x09, 0x09, 0x08, 0x08, 0x08, /* [160] -> [164] */ 219 0x08, 0x08, 0x08, 0x08, 0x08, /* [165] -> [169] */ 220 0x08, 0x07, 0x07, 0x07, 0x07, /* [170] -> [174] */ 221 0x07, 0x07, 0x07, 0x07, 0x07, /* [175] -> [179] */ 222 0x06, 0x06, 0x06, 0x06, 0x06, /* [180] -> [184] */ 223 0x06, 0x06, 0x06, 0x06, 0x05, /* [185] -> [189] */ 224 0x05, 0x05, 0x05, 0x05, 0x05, /* [190] -> [194] */ 225 0x05, 0x05, 0x05, 0x05, 0x04, /* [195] -> [199] */ 226 0x04, 0x04, 0x04, 0x04, 0x04, /* [200] -> [204] */ 227 0x04, 0x04, 0x04, 0x04, 0x03, /* [205] -> [209] */ 228 0x03, 0x03, 0x03, 0x03, 0x03, /* [210] -> [214] */ 229 0x03, 0x03, 0x03, 0x03, 0x03, /* [215] -> [219] */ 230 0x02, 0x02, 0x02, 0x02, 0x02, /* [220] -> [224] */ 231 0x02, 0x02, 0x02, 0x02, 0x02, /* [225] -> [229] */ 232 0x02, 0x01, 0x01, 0x01, 0x01, /* [230] -> [234] */ 233 0x01, 0x01, 0x01, 0x01, 0x01, /* [235] -> [239] */ 234 0x01, 0x01, 0x01, 0x00, 0x00, /* [240] -> [244] */ 235 0x00, 0x00, 0x00, 0x00, 0x00, /* [245] -> [249] */ 236 0x00, 0x00, 0x00, 0x00, 0x00, /* [250] -> [254] */ 237 0x00 /* [255] */ 238 }; 239 240 /* 241 * STREAMS Structures 242 */ 243 244 /* 245 * DDI Structures 246 */ 247 248 /* Device operations structure */ 249 static struct dev_ops audiocs_dev_ops = { 250 DEVO_REV, /* devo_rev */ 251 0, /* devo_refcnt */ 252 NULL, /* devo_getinfo */ 253 nulldev, /* devo_identify - obsolete */ 254 nulldev, /* devo_probe - not needed */ 255 audiocs_ddi_attach, /* devo_attach */ 256 audiocs_ddi_detach, /* devo_detach */ 257 nodev, /* devo_reset */ 258 NULL, /* devi_cb_ops */ 259 NULL, /* devo_bus_ops */ 260 audiocs_ddi_power, /* devo_power */ 261 ddi_quiesce_not_supported, /* devo_quiesce */ 262 }; 263 264 /* Linkage structure for loadable drivers */ 265 static struct modldrv audiocs_modldrv = { 266 &mod_driverops, /* drv_modops */ 267 CS4231_MOD_NAME, /* drv_linkinfo */ 268 &audiocs_dev_ops /* drv_dev_ops */ 269 }; 270 271 /* Module linkage structure */ 272 static struct modlinkage audiocs_modlinkage = { 273 MODREV_1, /* ml_rev */ 274 (void *)&audiocs_modldrv, /* ml_linkage */ 275 NULL /* NULL terminates the list */ 276 }; 277 278 279 /* ******* Loadable Module Configuration Entry Points ********************* */ 280 281 /* 282 * _init() 283 * 284 * Description: 285 * Implements _init(9E). 286 * 287 * Returns: 288 * mod_install() status, see mod_install(9f) 289 */ 290 int 291 _init(void) 292 { 293 int rv; 294 295 audio_init_ops(&audiocs_dev_ops, CS4231_NAME); 296 297 if ((rv = mod_install(&audiocs_modlinkage)) != 0) { 298 audio_fini_ops(&audiocs_dev_ops); 299 } 300 301 return (rv); 302 } 303 304 /* 305 * _fini() 306 * 307 * Description: 308 * Implements _fini(9E). 309 * 310 * Returns: 311 * mod_remove() status, see mod_remove(9f) 312 */ 313 int 314 _fini(void) 315 { 316 int rv; 317 318 if ((rv = mod_remove(&audiocs_modlinkage)) == 0) { 319 audio_fini_ops(&audiocs_dev_ops); 320 } 321 322 return (rv); 323 } 324 325 /* 326 * _info() 327 * 328 * Description: 329 * Implements _info(9E). 330 * 331 * Arguments: 332 * modinfo *modinfop Pointer to the opaque modinfo structure 333 * 334 * Returns: 335 * mod_info() status, see mod_info(9f) 336 */ 337 int 338 _info(struct modinfo *modinfop) 339 { 340 return (mod_info(&audiocs_modlinkage, modinfop)); 341 } 342 343 344 /* ******* Driver Entry Points ******************************************** */ 345 346 /* 347 * audiocs_ddi_attach() 348 * 349 * Description: 350 * Implement attach(9e). 351 * 352 * Arguments: 353 * dev_info_t *dip Pointer to the device's dev_info struct 354 * ddi_attach_cmd_t cmd Attach command 355 * 356 * Returns: 357 * DDI_SUCCESS The driver was initialized properly 358 * DDI_FAILURE The driver couldn't be initialized properly 359 */ 360 static int 361 audiocs_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 362 { 363 switch (cmd) { 364 case DDI_ATTACH: 365 return (audiocs_attach(dip)); 366 367 case DDI_RESUME: 368 return (audiocs_resume(dip)); 369 370 default: 371 return (DDI_FAILURE); 372 } 373 } 374 375 /* 376 * audiocs_ddi_detach() 377 * 378 * Description: 379 * Implement detach(9e). 380 * 381 * Arguments: 382 * dev_info_t *dip Pointer to the device's dev_info struct 383 * ddi_detach_cmd_t cmd Detach command 384 * 385 * Returns: 386 * DDI_SUCCESS Success. 387 * DDI_FAILURE Failure. 388 */ 389 static int 390 audiocs_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 391 { 392 switch (cmd) { 393 case DDI_DETACH: 394 return (audiocs_detach(dip)); 395 396 case DDI_SUSPEND: 397 return (audiocs_suspend(dip)); 398 399 default: 400 return (DDI_FAILURE); 401 } 402 } 403 404 /* 405 * audiocs_ddi_power() 406 * 407 * Description: 408 * Implements power(9E). 409 * 410 * Arguments: 411 * def_info_t *dip Ptr to the device's dev_info structure 412 * int component Which component to power up/down 413 * int level The power level for the component 414 * 415 * Returns: 416 * DDI_SUCCESS Power level changed, we always succeed 417 */ 418 static int 419 audiocs_ddi_power(dev_info_t *dip, int component, int level) 420 { 421 CS_state_t *state; 422 423 if (component != CS4231_COMPONENT) 424 return (DDI_FAILURE); 425 426 /* get the state structure */ 427 state = ddi_get_driver_private(dip); 428 429 ASSERT(!mutex_owned(&state->cs_lock)); 430 431 /* make sure we have some work to do */ 432 mutex_enter(&state->cs_lock); 433 434 /* 435 * We don't do anything if we're suspended. Suspend/resume diddles 436 * with power anyway. 437 */ 438 if (!state->cs_suspended) { 439 440 /* check the level change to see what we need to do */ 441 if (level == CS4231_PWR_OFF && state->cs_powered) { 442 443 /* power down and save the state */ 444 audiocs_power_down(state); 445 state->cs_powered = B_FALSE; 446 447 } else if (level == CS4231_PWR_ON && !state->cs_powered) { 448 449 /* power up */ 450 audiocs_power_up(state); 451 state->cs_powered = B_TRUE; 452 } 453 } 454 455 mutex_exit(&state->cs_lock); 456 457 ASSERT(!mutex_owned(&state->cs_lock)); 458 459 return (DDI_SUCCESS); 460 } 461 462 /* ******* Local Routines *************************************************** */ 463 464 static void 465 audiocs_destroy(CS_state_t *state) 466 { 467 if (state == NULL) 468 return; 469 470 for (int i = CS4231_PLAY; i <= CS4231_REC; i++) { 471 audiocs_free_engine(state->cs_engines[i]); 472 } 473 audiocs_del_controls(state); 474 475 if (state->cs_adev) { 476 audio_dev_free(state->cs_adev); 477 } 478 479 /* unmap the registers */ 480 CS4231_DMA_UNMAP_REGS(state); 481 482 /* destroy the state mutex */ 483 mutex_destroy(&state->cs_lock); 484 kmem_free(state, sizeof (*state)); 485 } 486 487 /* 488 * audiocs_attach() 489 * 490 * Description: 491 * Attach an instance of the CS4231 driver. This routine does the device 492 * dependent attach tasks. When it is complete it calls 493 * audio_dev_register() to register with the framework. 494 * 495 * Arguments: 496 * dev_info_t *dip Pointer to the device's dev_info struct 497 * 498 * Returns: 499 * DDI_SUCCESS The driver was initialized properly 500 * DDI_FAILURE The driver couldn't be initialized properly 501 */ 502 static int 503 audiocs_attach(dev_info_t *dip) 504 { 505 CS_state_t *state; 506 audio_dev_t *adev; 507 508 /* allocate the state structure */ 509 state = kmem_zalloc(sizeof (*state), KM_SLEEP); 510 state->cs_dip = dip; 511 ddi_set_driver_private(dip, state); 512 513 /* now fill it in, initialize the state mutexs first */ 514 mutex_init(&state->cs_lock, NULL, MUTEX_DRIVER, NULL); 515 516 /* 517 * audio state initialization... should always succeed, 518 * framework will message failure. 519 */ 520 if ((state->cs_adev = audio_dev_alloc(dip, 0)) == NULL) { 521 goto error; 522 } 523 adev = state->cs_adev; 524 audio_dev_set_description(adev, CS_DEV_CONFIG_ONBRD1); 525 audio_dev_add_info(adev, "Legacy codec: Crystal Semiconductor CS4231"); 526 527 /* initialize the audio state structures */ 528 if ((audiocs_init_state(state)) == DDI_FAILURE) { 529 audio_dev_warn(adev, "init_state() failed"); 530 goto error; 531 } 532 533 mutex_enter(&state->cs_lock); 534 535 /* initialize the audio chip */ 536 if ((audiocs_chip_init(state)) == DDI_FAILURE) { 537 mutex_exit(&state->cs_lock); 538 audio_dev_warn(adev, "chip_init() failed"); 539 goto error; 540 } 541 /* chip init will have powered us up */ 542 state->cs_powered = B_TRUE; 543 544 mutex_exit(&state->cs_lock); 545 546 /* finally register with framework to kick everything off */ 547 if (audio_dev_register(state->cs_adev) != DDI_SUCCESS) { 548 audio_dev_warn(state->cs_adev, "unable to register audio dev"); 549 } 550 551 /* everything worked out, so report the device */ 552 ddi_report_dev(dip); 553 554 return (DDI_SUCCESS); 555 556 error: 557 audiocs_destroy(state); 558 return (DDI_FAILURE); 559 } 560 561 /* 562 * audiocs_resume() 563 * 564 * Description: 565 * Resume a suspended device instance. 566 * 567 * Arguments: 568 * dev_info_t *dip Pointer to the device's dev_info struct 569 * 570 * Returns: 571 * DDI_SUCCESS The driver was initialized properly 572 * DDI_FAILURE The driver couldn't be initialized properly 573 */ 574 static int 575 audiocs_resume(dev_info_t *dip) 576 { 577 CS_state_t *state; 578 audio_dev_t *adev; 579 580 /* we've already allocated the state structure so get ptr */ 581 state = ddi_get_driver_private(dip); 582 adev = state->cs_adev; 583 584 ASSERT(dip == state->cs_dip); 585 ASSERT(!mutex_owned(&state->cs_lock)); 586 587 /* mark the Codec busy -- this should keep power(9e) away */ 588 (void) pm_busy_component(state->cs_dip, CS4231_COMPONENT); 589 590 /* power it up */ 591 audiocs_power_up(state); 592 state->cs_powered = B_TRUE; 593 594 mutex_enter(&state->cs_lock); 595 596 /* initialize the audio chip */ 597 if ((audiocs_chip_init(state)) == DDI_FAILURE) { 598 mutex_exit(&state->cs_lock); 599 audio_dev_warn(adev, "chip_init() failed"); 600 (void) pm_idle_component(state->cs_dip, CS4231_COMPONENT); 601 return (DDI_FAILURE); 602 } 603 604 state->cs_suspended = B_FALSE; 605 606 mutex_exit(&state->cs_lock); 607 608 /* 609 * We have already powered up the chip, but this alerts the 610 * framework to the fact. 611 */ 612 (void) pm_raise_power(dip, CS4231_COMPONENT, CS4231_PWR_ON); 613 (void) pm_idle_component(state->cs_dip, CS4231_COMPONENT); 614 615 audio_dev_resume(state->cs_adev); 616 617 return (DDI_SUCCESS); 618 } 619 620 /* 621 * audiocs_detach() 622 * 623 * Description: 624 * Detach an instance of the CS4231 driver. 625 * 626 * Arguments: 627 * dev_info_t *dip Pointer to the device's dev_info struct 628 * 629 * Returns: 630 * DDI_SUCCESS The driver was detached 631 * DDI_FAILURE The driver couldn't be detached (busy) 632 */ 633 static int 634 audiocs_detach(dev_info_t *dip) 635 { 636 CS_state_t *state; 637 audio_dev_t *adev; 638 ddi_acc_handle_t handle; 639 640 /* get the state structure */ 641 state = ddi_get_driver_private(dip); 642 handle = CODEC_HANDLE; 643 adev = state->cs_adev; 644 645 /* don't detach if still in use */ 646 if (audio_dev_unregister(adev) != DDI_SUCCESS) { 647 return (DDI_FAILURE); 648 } 649 650 if (state->cs_powered) { 651 /* 652 * Make sure the Codec and DMA engine are off. 653 */ 654 SELIDX(state, INTC_REG); 655 ANDIDX(state, ~(INTC_PEN|INTC_CEN), INTC_VALID_MASK); 656 657 /* make sure the DMA engine isn't going to do anything */ 658 CS4231_DMA_RESET(state); 659 660 /* 661 * power down the device, no reason to waste power without 662 * a driver 663 */ 664 (void) pm_lower_power(dip, CS4231_COMPONENT, CS4231_PWR_OFF); 665 } 666 667 audiocs_destroy(state); 668 669 return (DDI_SUCCESS); 670 } 671 672 /* 673 * audiocs_suspend() 674 * 675 * Description: 676 * Suspend an instance of the CS4231 driver. 677 * 678 * Arguments: 679 * dev_info_t *dip Pointer to the device's dev_info struct 680 * 681 * Returns: 682 * DDI_SUCCESS The driver was detached 683 * DDI_FAILURE The driver couldn't be detached 684 */ 685 static int 686 audiocs_suspend(dev_info_t *dip) 687 { 688 CS_state_t *state; 689 690 /* get the state structure */ 691 state = ddi_get_driver_private(dip); 692 693 mutex_enter(&state->cs_lock); 694 695 ASSERT(!state->cs_suspended); 696 697 audio_dev_suspend(state->cs_adev); 698 699 if (state->cs_powered) { 700 /* now we can power down the Codec */ 701 audiocs_power_down(state); 702 state->cs_powered = B_FALSE; 703 } 704 state->cs_suspended = B_TRUE; /* stop new ops */ 705 mutex_exit(&state->cs_lock); 706 707 return (DDI_SUCCESS); 708 } 709 710 #define PLAYCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY) 711 #define RECCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC) 712 #define MONCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR) 713 #define PCMVOL (PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL) 714 #define MAINVOL (PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL) 715 #define RECVOL (RECCTL | AUDIO_CTRL_FLAG_RECVOL) 716 #define MONVOL (MONCTL | AUDIO_CTRL_FLAG_MONVOL) 717 718 /* 719 * audiocs_alloc_ctrl 720 * 721 * Description: 722 * Allocates a control structure for the audio mixer. 723 * 724 * Arguments: 725 * CS_state_t *state Device soft state. 726 * uint32_t num Control number to allocate. 727 * uint64_t val Initial value. 728 * 729 * Returns: 730 * Pointer to newly allocated CS_ctrl_t structure. 731 */ 732 static CS_ctrl_t * 733 audiocs_alloc_ctrl(CS_state_t *state, uint32_t num, uint64_t val) 734 { 735 audio_ctrl_desc_t desc; 736 audio_ctrl_wr_t fn; 737 CS_ctrl_t *cc; 738 739 cc = kmem_zalloc(sizeof (*cc), KM_SLEEP); 740 cc->cc_state = state; 741 cc->cc_num = num; 742 743 bzero(&desc, sizeof (desc)); 744 745 switch (num) { 746 case CTL_VOLUME: 747 desc.acd_name = AUDIO_CTRL_ID_VOLUME; 748 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 749 desc.acd_minvalue = 0; 750 desc.acd_maxvalue = 100; 751 desc.acd_flags = PCMVOL; 752 fn = audiocs_set_ogain; 753 break; 754 755 case CTL_IGAIN: 756 desc.acd_name = AUDIO_CTRL_ID_RECGAIN; 757 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 758 desc.acd_minvalue = 0; 759 desc.acd_maxvalue = 100; 760 desc.acd_flags = RECVOL; 761 fn = audiocs_set_igain; 762 break; 763 764 case CTL_MGAIN: 765 desc.acd_name = AUDIO_CTRL_ID_MONGAIN; 766 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 767 desc.acd_minvalue = 0; 768 desc.acd_maxvalue = 100; 769 desc.acd_flags = MONVOL; 770 fn = audiocs_set_mgain; 771 break; 772 773 case CTL_INPUTS: 774 desc.acd_name = AUDIO_CTRL_ID_RECSRC; 775 desc.acd_type = AUDIO_CTRL_TYPE_ENUM; 776 desc.acd_minvalue = state->cs_imask; 777 desc.acd_maxvalue = state->cs_imask; 778 desc.acd_flags = RECCTL; 779 for (int i = 0; audiocs_inputs[i]; i++) { 780 desc.acd_enum[i] = audiocs_inputs[i]; 781 } 782 fn = audiocs_set_inputs; 783 784 break; 785 786 case CTL_OUTPUTS: 787 desc.acd_name = AUDIO_CTRL_ID_OUTPUTS; 788 desc.acd_type = AUDIO_CTRL_TYPE_ENUM; 789 desc.acd_minvalue = state->cs_omod; 790 desc.acd_maxvalue = state->cs_omask; 791 desc.acd_flags = PLAYCTL | AUDIO_CTRL_FLAG_MULTI; 792 for (int i = 0; audiocs_outputs[i]; i++) { 793 desc.acd_enum[i] = audiocs_outputs[i]; 794 } 795 fn = audiocs_set_outputs; 796 break; 797 798 case CTL_MICBOOST: 799 desc.acd_name = AUDIO_CTRL_ID_MICBOOST; 800 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN; 801 desc.acd_minvalue = 0; 802 desc.acd_maxvalue = 1; 803 desc.acd_flags = RECCTL; 804 fn = audiocs_set_micboost; 805 break; 806 } 807 808 cc->cc_val = val; 809 cc->cc_ctrl = audio_dev_add_control(state->cs_adev, &desc, 810 audiocs_get_value, fn, cc); 811 812 return (cc); 813 } 814 815 /* 816 * audiocs_free_ctrl 817 * 818 * Description: 819 * Frees a control and all resources associated with it. 820 * 821 * Arguments: 822 * CS_ctrl_t *cc Pointer to control structure. 823 */ 824 static void 825 audiocs_free_ctrl(CS_ctrl_t *cc) 826 { 827 if (cc == NULL) 828 return; 829 if (cc->cc_ctrl) 830 audio_dev_del_control(cc->cc_ctrl); 831 kmem_free(cc, sizeof (*cc)); 832 } 833 834 /* 835 * audiocs_add_controls 836 * 837 * Description: 838 * Allocates and registers all controls for this device. 839 * 840 * Arguments: 841 * CS_state_t *state Device soft state. 842 * 843 * Returns: 844 * DDI_SUCCESS All controls added and registered 845 * DDI_FAILURE At least one control was not added or registered. 846 */ 847 static int 848 audiocs_add_controls(CS_state_t *state) 849 { 850 #define ADD_CTRL(CTL, ID, VAL) \ 851 state->cs_##CTL = audiocs_alloc_ctrl(state, ID, VAL); \ 852 if (state->cs_##CTL == NULL) { \ 853 audio_dev_warn(state->cs_adev, \ 854 "unable to allocate %s control", #ID); \ 855 return (DDI_FAILURE); \ 856 } 857 858 ADD_CTRL(ogain, CTL_VOLUME, 0x4b4b); 859 ADD_CTRL(igain, CTL_IGAIN, 0x3232); 860 ADD_CTRL(mgain, CTL_MGAIN, 0); 861 ADD_CTRL(micboost, CTL_MICBOOST, 0); 862 ADD_CTRL(outputs, CTL_OUTPUTS, (state->cs_omask & ~state->cs_omod) | 863 (1U << OUTPUT_SPEAKER)); 864 ADD_CTRL(inputs, CTL_INPUTS, (1U << INPUT_MIC)); 865 866 return (DDI_SUCCESS); 867 } 868 869 /* 870 * audiocs_del_controls 871 * 872 * Description: 873 * Unregisters and frees all controls for this device. 874 * 875 * Arguments: 876 * CS_state_t *state Device soft state. 877 */ 878 void 879 audiocs_del_controls(CS_state_t *state) 880 { 881 audiocs_free_ctrl(state->cs_ogain); 882 audiocs_free_ctrl(state->cs_igain); 883 audiocs_free_ctrl(state->cs_mgain); 884 audiocs_free_ctrl(state->cs_micboost); 885 audiocs_free_ctrl(state->cs_inputs); 886 audiocs_free_ctrl(state->cs_outputs); 887 } 888 889 890 /* 891 * audiocs_chip_init() 892 * 893 * Description: 894 * Power up the audio core, initialize the audio Codec, prepare the chip 895 * for use. 896 * 897 * Arguments: 898 * CS_state_t *state The device's state structure 899 * 900 * Returns: 901 * DDI_SUCCESS Chip initialized and ready to use 902 * DDI_FAILURE Chip not initialized and not ready 903 */ 904 static int 905 audiocs_chip_init(CS_state_t *state) 906 { 907 ddi_acc_handle_t handle = CODEC_HANDLE; 908 909 /* make sure we are powered up */ 910 CS4231_DMA_POWER(state, CS4231_PWR_ON); 911 912 CS4231_DMA_RESET(state); 913 914 /* wait for the Codec before we continue */ 915 if (audiocs_poll_ready(state) == DDI_FAILURE) { 916 return (DDI_FAILURE); 917 } 918 919 /* activate registers 16 -> 31 */ 920 SELIDX(state, MID_REG); 921 ddi_put8(handle, &CS4231_IDR, MID_MODE2); 922 923 /* now figure out what version we have */ 924 SELIDX(state, VID_REG); 925 if (ddi_get8(handle, &CS4231_IDR) & VID_A) { 926 state->cs_revA = B_TRUE; 927 } else { 928 state->cs_revA = B_FALSE; 929 } 930 931 /* get rid of annoying popping by muting the output channels */ 932 SELIDX(state, LDACO_REG); 933 PUTIDX(state, LDACO_LDM | LDACO_MID_GAIN, LDAC0_VALID_MASK); 934 SELIDX(state, RDACO_REG); 935 PUTIDX(state, RDACO_RDM | RDACO_MID_GAIN, RDAC0_VALID_MASK); 936 937 /* initialize aux input channels to known gain values & muted */ 938 SELIDX(state, LAUX1_REG); 939 PUTIDX(state, LAUX1_LX1M | LAUX1_UNITY_GAIN, LAUX1_VALID_MASK); 940 SELIDX(state, RAUX1_REG); 941 PUTIDX(state, RAUX1_RX1M | RAUX1_UNITY_GAIN, RAUX1_VALID_MASK); 942 SELIDX(state, LAUX2_REG); 943 PUTIDX(state, LAUX2_LX2M | LAUX2_UNITY_GAIN, LAUX2_VALID_MASK); 944 SELIDX(state, RAUX2_REG); 945 PUTIDX(state, RAUX2_RX2M | RAUX2_UNITY_GAIN, RAUX2_VALID_MASK); 946 947 /* initialize aux input channels to known gain values & muted */ 948 SELIDX(state, LLIC_REG); 949 PUTIDX(state, LLIC_LLM | LLIC_UNITY_GAIN, LLIC_VALID_MASK); 950 SELIDX(state, RLIC_REG); 951 PUTIDX(state, RLIC_RLM | RLIC_UNITY_GAIN, RLIC_VALID_MASK); 952 953 /* program the sample rate, play and capture must be the same */ 954 SELIDX(state, FSDF_REG | IAR_MCE); 955 PUTIDX(state, FS_48000 | PDF_LINEAR16NE | PDF_STEREO, FSDF_VALID_MASK); 956 if (audiocs_poll_ready(state) == DDI_FAILURE) { 957 return (DDI_FAILURE); 958 } 959 960 SELIDX(state, CDF_REG | IAR_MCE); 961 PUTIDX(state, CDF_LINEAR16NE | CDF_STEREO, CDF_VALID_MASK); 962 if (audiocs_poll_ready(state) == DDI_FAILURE) { 963 return (DDI_FAILURE); 964 } 965 966 /* 967 * Set up the Codec for playback and capture disabled, dual DMA, and 968 * playback and capture DMA. 969 */ 970 SELIDX(state, (INTC_REG | IAR_MCE)); 971 PUTIDX(state, INTC_DDC | INTC_PDMA | INTC_CDMA, INTC_VALID_MASK); 972 if (audiocs_poll_ready(state) == DDI_FAILURE) { 973 return (DDI_FAILURE); 974 } 975 976 /* 977 * Turn on the output level bit to be 2.8 Vpp. Also, don't go to 0 on 978 * underflow. 979 */ 980 SELIDX(state, AFE1_REG); 981 PUTIDX(state, AFE1_OLB, AFE1_VALID_MASK); 982 983 /* turn on the high pass filter if Rev A */ 984 SELIDX(state, AFE2_REG); 985 if (state->cs_revA) { 986 PUTIDX(state, AFE2_HPF, AFE2_VALID_MASK); 987 } else { 988 PUTIDX(state, 0, AFE2_VALID_MASK); 989 } 990 991 992 /* clear the play and capture interrupt flags */ 993 SELIDX(state, AFS_REG); 994 ddi_put8(handle, &CS4231_STATUS, (AFS_RESET_STATUS)); 995 996 /* the play and record gains will be set by the audio mixer */ 997 998 /* unmute the output */ 999 SELIDX(state, LDACO_REG); 1000 ANDIDX(state, ~LDACO_LDM, LDAC0_VALID_MASK); 1001 SELIDX(state, RDACO_REG); 1002 ANDIDX(state, ~RDACO_RDM, RDAC0_VALID_MASK); 1003 1004 /* unmute the mono speaker and mute mono in */ 1005 SELIDX(state, MIOC_REG); 1006 PUTIDX(state, MIOC_MIM, MIOC_VALID_MASK); 1007 1008 audiocs_configure_output(state); 1009 audiocs_configure_input(state); 1010 1011 return (DDI_SUCCESS); 1012 } 1013 1014 /* 1015 * audiocs_init_state() 1016 * 1017 * Description: 1018 * This routine initializes the audio driver's state structure and 1019 * maps in the registers. This also includes reading the properties. 1020 * 1021 * CAUTION: This routine maps the registers and initializes a mutex. 1022 * Failure cleanup is handled by cs4231_attach(). It is not 1023 * handled locally by this routine. 1024 * 1025 * Arguments: 1026 * CS_state_t *state The device's state structure 1027 * 1028 * Returns: 1029 * DDI_SUCCESS State structure initialized 1030 * DDI_FAILURE State structure not initialized 1031 */ 1032 static int 1033 audiocs_init_state(CS_state_t *state) 1034 { 1035 audio_dev_t *adev = state->cs_adev; 1036 dev_info_t *dip = state->cs_dip; 1037 char *prop_str; 1038 char *pm_comp[] = { 1039 "NAME=audiocs audio device", 1040 "0=off", 1041 "1=on" }; 1042 1043 /* set up the pm-components */ 1044 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, dip, 1045 "pm-components", pm_comp, 3) != DDI_PROP_SUCCESS) { 1046 audio_dev_warn(adev, "couldn't create pm-components property"); 1047 return (DDI_FAILURE); 1048 } 1049 1050 /* figure out which DMA engine hardware we have */ 1051 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1052 "dma-model", &prop_str) == DDI_PROP_SUCCESS) { 1053 if (strcmp(prop_str, "eb2dma") == 0) { 1054 state->cs_dma_engine = EB2_DMA; 1055 state->cs_dma_ops = &cs4231_eb2dma_ops; 1056 } else { 1057 state->cs_dma_engine = APC_DMA; 1058 state->cs_dma_ops = &cs4231_apcdma_ops; 1059 } 1060 ddi_prop_free(prop_str); 1061 } else { 1062 state->cs_dma_engine = APC_DMA; 1063 state->cs_dma_ops = &cs4231_apcdma_ops; 1064 } 1065 1066 /* cs_regs, cs_eb2_regs and cs_handles filled in later */ 1067 1068 /* most of what's left is filled in when the registers are mapped */ 1069 1070 audiocs_get_ports(state); 1071 1072 /* Allocate engines, must be done before register mapping called */ 1073 if ((audiocs_alloc_engine(state, CS4231_PLAY) != DDI_SUCCESS) || 1074 (audiocs_alloc_engine(state, CS4231_REC) != DDI_SUCCESS)) { 1075 return (DDI_FAILURE); 1076 } 1077 1078 /* Map in the registers */ 1079 if (CS4231_DMA_MAP_REGS(state) == DDI_FAILURE) { 1080 return (DDI_FAILURE); 1081 } 1082 1083 1084 /* Allocate and add controls, must be done *after* registers mapped */ 1085 if (audiocs_add_controls(state) != DDI_SUCCESS) { 1086 return (DDI_FAILURE); 1087 } 1088 1089 state->cs_suspended = B_FALSE; 1090 state->cs_powered = B_FALSE; 1091 1092 return (DDI_SUCCESS); 1093 } 1094 1095 /* 1096 * audiocs_get_ports() 1097 * 1098 * Description: 1099 * Get which audiocs h/w version we have and use this to 1100 * determine the input and output ports as well whether or not 1101 * the hardware has internal loopbacks or not. We also have three 1102 * different ways for the properties to be specified, which we 1103 * also need to worry about. 1104 * 1105 * Vers Platform(s) DMA eng. audio-module** loopback 1106 * a SS-4+/SS-5+ apcdma no no 1107 * b Ultra-1&2 apcdma no yes 1108 * c positron apcdma no yes 1109 * d PPC - retired 1110 * e x86 - retired 1111 * f tazmo eb2dma Perigee no 1112 * g tazmo eb2dma Quark yes 1113 * h darwin+ eb2dma no N/A 1114 * 1115 * Vers model~ aux1* aux2* 1116 * a N/A N/A N/A 1117 * b N/A N/A N/A 1118 * c N/A N/A N/A 1119 * d retired 1120 * e retired 1121 * f SUNW,CS4231f N/A N/A 1122 * g SUNW,CS4231g N/A N/A 1123 * h SUNW,CS4231h cdrom none 1124 * 1125 * * = Replaces internal-loopback for latest property type, can be 1126 * set to "cdrom", "loopback", or "none". 1127 * 1128 * ** = For plugin audio modules only. Starting with darwin, this 1129 * property is replaces by the model property. 1130 * 1131 * ~ = Replaces audio-module. 1132 * 1133 * + = Has the capability of having a cable run from the internal 1134 * CD-ROM to the audio device. 1135 * 1136 * N/A = Not applicable, the property wasn't created for early 1137 * platforms, or the property has been retired. 1138 * 1139 * NOTE: Older tazmo and quark machines don't have the model property. 1140 * 1141 * Arguments: 1142 * CS_state_t *state The device's state structure 1143 */ 1144 static void 1145 audiocs_get_ports(CS_state_t *state) 1146 { 1147 dev_info_t *dip = state->cs_dip; 1148 audio_dev_t *adev = state->cs_adev; 1149 char *prop_str; 1150 1151 /* First we set the common ports, etc. */ 1152 state->cs_omask = state->cs_omod = 1153 (1U << OUTPUT_SPEAKER) | 1154 (1U << OUTPUT_HEADPHONES) | 1155 (1U << OUTPUT_LINEOUT); 1156 state->cs_imask = 1157 (1U << INPUT_MIC) | 1158 (1U << INPUT_LINEIN) | 1159 (1U << INPUT_STEREOMIX); 1160 1161 /* now we try the new "model" property */ 1162 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1163 "model", &prop_str) == DDI_PROP_SUCCESS) { 1164 if (strcmp(prop_str, "SUNW,CS4231h") == 0) { 1165 /* darwin */ 1166 audio_dev_set_version(adev, CS_DEV_VERSION_H); 1167 state->cs_imask |= (1U << INPUT_CD); 1168 state->cs_omod = (1U << OUTPUT_SPEAKER); 1169 } else if (strcmp(prop_str, "SUNW,CS4231g") == 0) { 1170 /* quark audio module */ 1171 audio_dev_set_version(adev, CS_DEV_VERSION_G); 1172 /* 1173 * NB: This could do SUNVTS LOOPBACK, but we 1174 * don't support it for now... owing to no 1175 * support in framework. 1176 */ 1177 } else if (strcmp(prop_str, "SUNW,CS4231f") == 0) { 1178 /* tazmo */ 1179 audio_dev_set_version(adev, CS_DEV_VERSION_F); 1180 } else { 1181 audio_dev_set_version(adev, prop_str); 1182 audio_dev_warn(adev, 1183 "unknown audio model: %s, some parts of " 1184 "audio may not work correctly", prop_str); 1185 } 1186 ddi_prop_free(prop_str); /* done with the property */ 1187 } else { /* now try the older "audio-module" property */ 1188 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 1189 DDI_PROP_DONTPASS, "audio-module", &prop_str) == 1190 DDI_PROP_SUCCESS) { 1191 switch (*prop_str) { 1192 case 'Q': /* quark audio module */ 1193 audio_dev_set_version(adev, CS_DEV_VERSION_G); 1194 /* See quark comment above about SunVTS */ 1195 break; 1196 case 'P': /* tazmo */ 1197 audio_dev_set_version(adev, CS_DEV_VERSION_F); 1198 break; 1199 default: 1200 audio_dev_set_version(adev, prop_str); 1201 audio_dev_warn(adev, 1202 "unknown audio module: %s, some " 1203 "parts of audio may not work correctly", 1204 prop_str); 1205 break; 1206 } 1207 ddi_prop_free(prop_str); /* done with the prop */ 1208 } else { /* now try heuristics, ;-( */ 1209 if (ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1210 DDI_PROP_DONTPASS, "internal-loopback", B_FALSE)) { 1211 if (state->cs_dma_engine == EB2_DMA) { 1212 audio_dev_set_version(adev, 1213 CS_DEV_VERSION_C); 1214 } else { 1215 audio_dev_set_version(adev, 1216 CS_DEV_VERSION_B); 1217 } 1218 /* 1219 * Again, we don't support SunVTS for these 1220 * boards, although we potentially could. 1221 */ 1222 } else { 1223 audio_dev_set_version(adev, CS_DEV_VERSION_A); 1224 state->cs_imask |= (1U << INPUT_CD); 1225 } 1226 } 1227 } 1228 } 1229 1230 /* 1231 * audiocs_power_up() 1232 * 1233 * Description: 1234 * Power up the Codec and restore the codec's registers. 1235 * 1236 * NOTE: We don't worry about locking since the only routines 1237 * that may call us are attach() and power() Both of 1238 * which should be the only threads in the driver. 1239 * 1240 * Arguments: 1241 * CS_state_t *state The device's state structure 1242 */ 1243 static void 1244 audiocs_power_up(CS_state_t *state) 1245 { 1246 ddi_acc_handle_t handle = CODEC_HANDLE; 1247 int i; 1248 1249 /* turn on the Codec */ 1250 CS4231_DMA_POWER(state, CS4231_PWR_ON); 1251 1252 /* reset the DMA engine(s) */ 1253 CS4231_DMA_RESET(state); 1254 1255 (void) audiocs_poll_ready(state); 1256 1257 /* 1258 * Reload the Codec's registers, the DMA engines will be 1259 * taken care of when play and record start up again. But 1260 * first enable registers 16 -> 31. 1261 */ 1262 SELIDX(state, MID_REG); 1263 PUTIDX(state, state->cs_save[MID_REG], MID_VALID_MASK); 1264 1265 for (i = 0; i < CS4231_REGS; i++) { 1266 /* restore Codec registers */ 1267 SELIDX(state, (i | IAR_MCE)); 1268 ddi_put8(handle, &CS4231_IDR, state->cs_save[i]); 1269 (void) audiocs_poll_ready(state); 1270 } 1271 /* clear MCE bit */ 1272 SELIDX(state, 0); 1273 } 1274 1275 /* 1276 * audiocs_power_down() 1277 * 1278 * Description: 1279 * Power down the Codec and save the codec's registers. 1280 * 1281 * NOTE: See the note in cs4231_power_up() about locking. 1282 * 1283 * Arguments: 1284 * CS_state_t *state The device's state structure 1285 */ 1286 static void 1287 audiocs_power_down(CS_state_t *state) 1288 { 1289 ddi_acc_handle_t handle; 1290 int i; 1291 1292 handle = state->cs_handles.cs_codec_hndl; 1293 1294 /* 1295 * We are powering down, so we don't need to do a thing with 1296 * the DMA engines. However, we do need to save the Codec 1297 * registers. 1298 */ 1299 1300 for (i = 0; i < CS4231_REGS; i++) { 1301 /* save Codec regs */ 1302 SELIDX(state, i); 1303 state->cs_save[i] = ddi_get8(handle, &CS4231_IDR); 1304 } 1305 1306 /* turn off the Codec */ 1307 CS4231_DMA_POWER(state, CS4231_PWR_OFF); 1308 1309 } /* cs4231_power_down() */ 1310 1311 /* 1312 * audiocs_configure_input() 1313 * 1314 * Description: 1315 * Configure input properties of the mixer (e.g. igain, ports). 1316 * 1317 * Arguments: 1318 * CS_state_t *state The device's state structure 1319 */ 1320 static void 1321 audiocs_configure_input(CS_state_t *state) 1322 { 1323 uint8_t l, r; 1324 uint64_t inputs; 1325 uint64_t micboost; 1326 1327 ASSERT(mutex_owned(&state->cs_lock)); 1328 1329 inputs = state->cs_inputs->cc_val; 1330 micboost = state->cs_micboost->cc_val; 1331 r = (state->cs_igain->cc_val & 0xff); 1332 l = ((state->cs_igain->cc_val & 0xff00) >> 8); 1333 1334 /* rescale these for our atten array */ 1335 l = (((uint32_t)l * 255) / 100) & 0xff; 1336 r = (((uint32_t)r * 255) / 100) & 0xff; 1337 1338 /* we downshift by 4 bits -- igain only has 16 possible values */ 1339 /* NB: that we do not scale here! The SADA driver didn't do so. */ 1340 l = l >> 4; 1341 r = r >> 4; 1342 1343 if (inputs & (1U << INPUT_MIC)) { 1344 l |= LADCI_LMIC; 1345 r |= RADCI_RMIC; 1346 } 1347 if (inputs & (1U << INPUT_LINEIN)) { 1348 l |= LADCI_LLINE; 1349 r |= RADCI_RLINE; 1350 } 1351 if (inputs & (1U << INPUT_CD)) { 1352 /* note that SunVTS also uses this */ 1353 l |= LADCI_LAUX1; 1354 r |= RADCI_RAUX1; 1355 } 1356 if (inputs & (1U << INPUT_STEREOMIX)) { 1357 l |= LADCI_LLOOP; 1358 r |= RADCI_RLOOP; 1359 } 1360 if (micboost) { 1361 l |= LADCI_LMGE; 1362 r |= RADCI_RMGE; 1363 } 1364 1365 SELIDX(state, LADCI_REG); 1366 PUTIDX(state, l, LADCI_VALID_MASK); 1367 1368 SELIDX(state, RADCI_REG); 1369 PUTIDX(state, r, RADCI_VALID_MASK); 1370 } 1371 1372 /* 1373 * audiocs_configure_output() 1374 * 1375 * Description: 1376 * Configure output properties of the mixer (e.g. ogain, mgain). 1377 * 1378 * Arguments: 1379 * CS_state_t *state The device's state structure 1380 */ 1381 static void 1382 audiocs_configure_output(CS_state_t *state) 1383 { 1384 uint64_t outputs; 1385 uint8_t l, r; 1386 uint8_t rmute, lmute; 1387 uint8_t mgain; 1388 ddi_acc_handle_t handle = CODEC_HANDLE; 1389 1390 rmute = lmute = 0; 1391 1392 ASSERT(mutex_owned(&state->cs_lock)); 1393 1394 outputs = state->cs_outputs->cc_val; 1395 1396 /* port selection */ 1397 SELIDX(state, MIOC_REG); 1398 if (outputs & (1U << OUTPUT_SPEAKER)) { 1399 ANDIDX(state, ~MIOC_MONO_SPKR_MUTE, MIOC_VALID_MASK); 1400 } else { 1401 ORIDX(state, MIOC_MONO_SPKR_MUTE, MIOC_VALID_MASK); 1402 } 1403 SELIDX(state, PC_REG); 1404 if (outputs & (1U << OUTPUT_HEADPHONES)) { 1405 ANDIDX(state, ~PC_HEADPHONE_MUTE, PC_VALID_MASK); 1406 } else { 1407 ORIDX(state, PC_HEADPHONE_MUTE, PC_VALID_MASK); 1408 } 1409 SELIDX(state, PC_REG); 1410 if (outputs & (1U << OUTPUT_LINEOUT)) { 1411 ANDIDX(state, ~PC_LINE_OUT_MUTE, PC_VALID_MASK); 1412 } else { 1413 ORIDX(state, PC_LINE_OUT_MUTE, PC_VALID_MASK); 1414 } 1415 1416 /* monitor gain */ 1417 mgain = cs4231_atten[((state->cs_mgain->cc_val * 255) / 100) & 0xff]; 1418 SELIDX(state, LC_REG); 1419 if (mgain == 0) { 1420 /* disable loopbacks when gain == 0 */ 1421 PUTIDX(state, LC_OFF, LC_VALID_MASK); 1422 } else { 1423 /* we use cs4231_atten[] to linearize attenuation */ 1424 PUTIDX(state, (mgain << 2) | LC_LBE, LC_VALID_MASK); 1425 } 1426 1427 /* output gain */ 1428 l = ((state->cs_ogain->cc_val >> 8) & 0xff); 1429 r = (state->cs_ogain->cc_val & 0xff); 1430 if (l == 0) { 1431 lmute = LDACO_LDM; 1432 } 1433 if (r == 0) { 1434 rmute = RDACO_RDM; 1435 } 1436 1437 /* rescale these for our atten array */ 1438 l = cs4231_atten[(((uint32_t)l * 255) / 100) & 0xff] | lmute; 1439 r = cs4231_atten[(((uint32_t)r * 255) / 100) & 0xff] | rmute; 1440 1441 SELIDX(state, LDACO_REG); 1442 PUTIDX(state, l, LDAC0_VALID_MASK); 1443 SELIDX(state, RDACO_REG); 1444 PUTIDX(state, r, RDAC0_VALID_MASK); 1445 } 1446 1447 /* 1448 * audiocs_get_value() 1449 * 1450 * Description: 1451 * Get a control value 1452 * 1453 * Arguments: 1454 * void *arg The device's state structure 1455 * uint64_t *valp Pointer to store value. 1456 * 1457 * Returns: 1458 * 0 The Codec parameter has been retrieved. 1459 */ 1460 static int 1461 audiocs_get_value(void *arg, uint64_t *valp) 1462 { 1463 CS_ctrl_t *cc = arg; 1464 CS_state_t *state = cc->cc_state; 1465 1466 mutex_enter(&state->cs_lock); 1467 *valp = cc->cc_val; 1468 mutex_exit(&state->cs_lock); 1469 return (0); 1470 } 1471 1472 1473 /* 1474 * audiocs_set_ogain() 1475 * 1476 * Description: 1477 * Set the play gain. 1478 * 1479 * Arguments: 1480 * void *arg The device's state structure 1481 * uint64_t val The gain to set (both left and right) 1482 * 1483 * Returns: 1484 * 0 The Codec parameter has been set 1485 */ 1486 static int 1487 audiocs_set_ogain(void *arg, uint64_t val) 1488 { 1489 CS_ctrl_t *cc = arg; 1490 CS_state_t *state = cc->cc_state; 1491 1492 if ((val & ~0xffff) || 1493 ((val & 0xff) > 100) || 1494 (((val & 0xff00) >> 8) > 100)) 1495 return (EINVAL); 1496 1497 mutex_enter(&state->cs_lock); 1498 cc->cc_val = val; 1499 audiocs_configure_output(state); 1500 mutex_exit(&state->cs_lock); 1501 return (0); 1502 } 1503 1504 /* 1505 * audiocs_set_micboost() 1506 * 1507 * Description: 1508 * Set the 20 dB microphone boost. 1509 * 1510 * Arguments: 1511 * void *arg The device's state structure 1512 * uint64_t val The 1 to enable, 0 to disable. 1513 * 1514 * Returns: 1515 * 0 The Codec parameter has been set 1516 */ 1517 static int 1518 audiocs_set_micboost(void *arg, uint64_t val) 1519 { 1520 CS_ctrl_t *cc = arg; 1521 CS_state_t *state = cc->cc_state; 1522 1523 mutex_enter(&state->cs_lock); 1524 cc->cc_val = val ? B_TRUE : B_FALSE; 1525 audiocs_configure_input(state); 1526 mutex_exit(&state->cs_lock); 1527 return (0); 1528 } 1529 1530 /* 1531 * audiocs_set_igain() 1532 * 1533 * Description: 1534 * Set the record gain. 1535 * 1536 * Arguments: 1537 * void *arg The device's state structure 1538 * uint64_t val The gain to set (both left and right) 1539 * 1540 * Returns: 1541 * 0 The Codec parameter has been set 1542 */ 1543 static int 1544 audiocs_set_igain(void *arg, uint64_t val) 1545 { 1546 CS_ctrl_t *cc = arg; 1547 CS_state_t *state = cc->cc_state; 1548 1549 if ((val & ~0xffff) || 1550 ((val & 0xff) > 100) || 1551 (((val & 0xff00) >> 8) > 100)) 1552 return (EINVAL); 1553 1554 mutex_enter(&state->cs_lock); 1555 cc->cc_val = val; 1556 audiocs_configure_input(state); 1557 mutex_exit(&state->cs_lock); 1558 1559 return (0); 1560 } 1561 1562 /* 1563 * audiocs_set_inputs() 1564 * 1565 * Description: 1566 * Set the input ports. 1567 * 1568 * Arguments: 1569 * void *arg The device's state structure 1570 * uint64_t val The mask of output ports. 1571 * 1572 * Returns: 1573 * 0 The Codec parameter has been set 1574 */ 1575 static int 1576 audiocs_set_inputs(void *arg, uint64_t val) 1577 { 1578 CS_ctrl_t *cc = arg; 1579 CS_state_t *state = cc->cc_state; 1580 1581 if (val & ~(state->cs_imask)) 1582 return (EINVAL); 1583 1584 mutex_enter(&state->cs_lock); 1585 cc->cc_val = val; 1586 audiocs_configure_input(state); 1587 mutex_exit(&state->cs_lock); 1588 1589 return (0); 1590 } 1591 1592 /* 1593 * audiocs_set_outputs() 1594 * 1595 * Description: 1596 * Set the output ports. 1597 * 1598 * Arguments: 1599 * void *arg The device's state structure 1600 * uint64_t val The mask of input ports. 1601 * 1602 * Returns: 1603 * 0 The Codec parameter has been set 1604 */ 1605 static int 1606 audiocs_set_outputs(void *arg, uint64_t val) 1607 { 1608 CS_ctrl_t *cc = arg; 1609 CS_state_t *state = cc->cc_state; 1610 1611 if ((val & ~(state->cs_omod)) != 1612 (state->cs_omask & ~state->cs_omod)) 1613 return (EINVAL); 1614 1615 mutex_enter(&state->cs_lock); 1616 cc->cc_val = val; 1617 audiocs_configure_output(state); 1618 mutex_exit(&state->cs_lock); 1619 1620 return (0); 1621 } 1622 1623 /* 1624 * audiocs_set_mgain() 1625 * 1626 * Description: 1627 * Set the monitor gain. 1628 * 1629 * Arguments: 1630 * void *arg The device's state structure 1631 * uint64_t val The gain to set (monoaural).) 1632 * 1633 * Returns: 1634 * 0 The Codec parameter has been set 1635 */ 1636 static int 1637 audiocs_set_mgain(void *arg, uint64_t gain) 1638 { 1639 CS_ctrl_t *cc = arg; 1640 CS_state_t *state = cc->cc_state; 1641 1642 if (gain > 100) 1643 return (EINVAL); 1644 1645 mutex_enter(&state->cs_lock); 1646 cc->cc_val = gain; 1647 audiocs_configure_output(state); 1648 mutex_exit(&state->cs_lock); 1649 1650 return (0); 1651 } 1652 1653 /* 1654 * audiocs_open() 1655 * 1656 * Description: 1657 * Opens a DMA engine for use. 1658 * 1659 * Arguments: 1660 * void *arg The DMA engine to set up 1661 * int flag Open flags 1662 * unsigned *nframesp Receives number of frames 1663 * caddr_t *bufp Receives kernel data buffer 1664 * 1665 * Returns: 1666 * 0 on success 1667 * errno on failure 1668 */ 1669 static int 1670 audiocs_open(void *arg, int flag, unsigned *nframesp, caddr_t *bufp) 1671 { 1672 CS_engine_t *eng = arg; 1673 CS_state_t *state = eng->ce_state; 1674 dev_info_t *dip = state->cs_dip; 1675 1676 _NOTE(ARGUNUSED(flag)); 1677 1678 (void) pm_busy_component(dip, CS4231_COMPONENT); 1679 if (pm_raise_power(dip, CS4231_COMPONENT, CS4231_PWR_ON) == 1680 DDI_FAILURE) { 1681 1682 /* match the busy call above */ 1683 (void) pm_idle_component(dip, CS4231_COMPONENT); 1684 1685 audio_dev_warn(state->cs_adev, "power up failed"); 1686 } 1687 1688 eng->ce_count = 0; 1689 *nframesp = CS4231_NFRAMES; 1690 *bufp = eng->ce_kaddr; 1691 1692 return (0); 1693 } 1694 1695 /* 1696 * audiocs_close() 1697 * 1698 * Description: 1699 * Closes an audio DMA engine that was previously opened. Since 1700 * nobody is using it, we take this opportunity to possibly power 1701 * down the entire device. 1702 * 1703 * Arguments: 1704 * void *arg The DMA engine to shut down 1705 */ 1706 static void 1707 audiocs_close(void *arg) 1708 { 1709 CS_engine_t *eng = arg; 1710 CS_state_t *state = eng->ce_state; 1711 1712 (void) pm_idle_component(state->cs_dip, CS4231_COMPONENT); 1713 } 1714 1715 /* 1716 * audiocs_stop() 1717 * 1718 * Description: 1719 * This is called by the framework to stop an engine that is 1720 * transferring data. 1721 * 1722 * Arguments: 1723 * void *arg The DMA engine to stop 1724 */ 1725 static void 1726 audiocs_stop(void *arg) 1727 { 1728 CS_engine_t *eng = arg; 1729 CS_state_t *state = eng->ce_state; 1730 ddi_acc_handle_t handle = CODEC_HANDLE; 1731 1732 mutex_enter(&state->cs_lock); 1733 /* 1734 * Stop the DMA engine. 1735 */ 1736 CS4231_DMA_STOP(state, eng); 1737 1738 /* 1739 * Stop the codec. 1740 */ 1741 SELIDX(state, INTC_REG); 1742 ANDIDX(state, ~(eng->ce_codec_en), INTC_VALID_MASK); 1743 mutex_exit(&state->cs_lock); 1744 } 1745 1746 /* 1747 * audiocs_start() 1748 * 1749 * Description: 1750 * This is called by the framework to start an engine transferring data. 1751 * 1752 * Arguments: 1753 * void *arg The DMA engine to start 1754 * 1755 * Returns: 1756 * 0 on success, an errno otherwise 1757 */ 1758 static int 1759 audiocs_start(void *arg) 1760 { 1761 CS_engine_t *eng = arg; 1762 CS_state_t *state = eng->ce_state; 1763 ddi_acc_handle_t handle = CODEC_HANDLE; 1764 uint8_t mask; 1765 uint8_t value; 1766 uint8_t reg; 1767 int rv; 1768 1769 mutex_enter(&state->cs_lock); 1770 1771 if (eng->ce_num == CS4231_PLAY) { 1772 /* sample rate only set on play side */ 1773 value = FS_48000 | PDF_STEREO | PDF_LINEAR16NE; 1774 reg = FSDF_REG; 1775 mask = FSDF_VALID_MASK; 1776 } else { 1777 value = CDF_STEREO | CDF_LINEAR16NE; 1778 reg = CDF_REG; 1779 mask = CDF_VALID_MASK; 1780 } 1781 eng->ce_curoff = 0; 1782 eng->ce_curidx = 0; 1783 1784 SELIDX(state, reg | IAR_MCE); 1785 PUTIDX(state, value, mask); 1786 1787 if (audiocs_poll_ready(state) != DDI_SUCCESS) { 1788 rv = EIO; 1789 } else if (CS4231_DMA_START(state, eng) != DDI_SUCCESS) { 1790 rv = EIO; 1791 } else { 1792 /* 1793 * Start the codec. 1794 */ 1795 SELIDX(state, INTC_REG); 1796 ORIDX(state, eng->ce_codec_en, INTC_VALID_MASK); 1797 rv = 0; 1798 } 1799 1800 mutex_exit(&state->cs_lock); 1801 return (rv); 1802 } 1803 1804 /* 1805 * audiocs_format() 1806 * 1807 * Description: 1808 * Called by the framework to query the format of the device. 1809 * 1810 * Arguments: 1811 * void *arg The DMA engine to query 1812 * 1813 * Returns: 1814 * AUDIO_FORMAT_S16_NE 1815 */ 1816 static int 1817 audiocs_format(void *arg) 1818 { 1819 _NOTE(ARGUNUSED(arg)); 1820 1821 return (AUDIO_FORMAT_S16_NE); 1822 } 1823 1824 /* 1825 * audiocs_channels() 1826 * 1827 * Description: 1828 * Called by the framework to query the channels of the device. 1829 * 1830 * Arguments: 1831 * void *arg The DMA engine to query 1832 * 1833 * Returns: 1834 * 2 (stereo) 1835 */ 1836 static int 1837 audiocs_channels(void *arg) 1838 { 1839 _NOTE(ARGUNUSED(arg)); 1840 1841 return (2); 1842 } 1843 1844 /* 1845 * audiocs_rates() 1846 * 1847 * Description: 1848 * Called by the framework to query the sample rate of the device. 1849 * 1850 * Arguments: 1851 * void *arg The DMA engine to query 1852 * 1853 * Returns: 1854 * 48000 1855 */ 1856 static int 1857 audiocs_rate(void *arg) 1858 { 1859 _NOTE(ARGUNUSED(arg)); 1860 1861 return (48000); 1862 } 1863 1864 /* 1865 * audiocs_count() 1866 * 1867 * Description: 1868 * This is called by the framework to get the engine's frame counter 1869 * 1870 * Arguments: 1871 * void *arg The DMA engine to query 1872 * 1873 * Returns: 1874 * frame count for current engine 1875 */ 1876 static uint64_t 1877 audiocs_count(void *arg) 1878 { 1879 CS_engine_t *eng = arg; 1880 CS_state_t *state = eng->ce_state; 1881 uint64_t val; 1882 uint32_t off; 1883 1884 mutex_enter(&state->cs_lock); 1885 1886 off = CS4231_DMA_ADDR(state, eng); 1887 ASSERT(off >= eng->ce_paddr); 1888 off -= eng->ce_paddr; 1889 1890 /* 1891 * Every now and then, we get a value that is just a wee bit 1892 * too large. This seems to be a small value related to 1893 * prefetch. Rather than believe it, we just assume the last 1894 * offset in the buffer. This should allow us to handle 1895 * wraps, but without inserting bogus sample counts. 1896 */ 1897 if (off >= CS4231_BUFSZ) { 1898 off = CS4231_BUFSZ - 4; 1899 } 1900 1901 off /= 4; 1902 1903 val = (off >= eng->ce_curoff) ? 1904 off - eng->ce_curoff : 1905 off + CS4231_NFRAMES - eng->ce_curoff; 1906 1907 eng->ce_count += val; 1908 eng->ce_curoff = off; 1909 val = eng->ce_count; 1910 1911 /* while here, possibly reload the next address */ 1912 CS4231_DMA_RELOAD(state, eng); 1913 mutex_exit(&state->cs_lock); 1914 1915 return (val); 1916 } 1917 1918 /* 1919 * audiocs_sync() 1920 * 1921 * Description: 1922 * This is called by the framework to synchronize DMA caches. 1923 * 1924 * Arguments: 1925 * void *arg The DMA engine to sync 1926 */ 1927 static void 1928 audiocs_sync(void *arg, unsigned nframes) 1929 { 1930 CS_engine_t *eng = arg; 1931 _NOTE(ARGUNUSED(nframes)); 1932 1933 (void) ddi_dma_sync(eng->ce_dmah, 0, 0, eng->ce_syncdir); 1934 } 1935 1936 /* 1937 * audiocs_alloc_engine() 1938 * 1939 * Description: 1940 * Allocates the DMA handles and the memory for the DMA engine. 1941 * 1942 * Arguments: 1943 * CS_state_t *dip Pointer to the device's soft state 1944 * int num Engine number, CS4231_PLAY or CS4231_REC. 1945 * 1946 * Returns: 1947 * DDI_SUCCESS Engine initialized. 1948 * DDI_FAILURE Engine not initialized. 1949 */ 1950 int 1951 audiocs_alloc_engine(CS_state_t *state, int num) 1952 { 1953 unsigned caps; 1954 int dir; 1955 int rc; 1956 audio_dev_t *adev; 1957 dev_info_t *dip; 1958 CS_engine_t *eng; 1959 uint_t ccnt; 1960 ddi_dma_cookie_t dmac; 1961 size_t bufsz; 1962 1963 static ddi_device_acc_attr_t buf_attr = { 1964 DDI_DEVICE_ATTR_V0, 1965 DDI_NEVERSWAP_ACC, 1966 DDI_STRICTORDER_ACC 1967 }; 1968 1969 adev = state->cs_adev; 1970 dip = state->cs_dip; 1971 1972 eng = kmem_zalloc(sizeof (*eng), KM_SLEEP); 1973 eng->ce_state = state; 1974 eng->ce_started = B_FALSE; 1975 eng->ce_num = num; 1976 1977 switch (num) { 1978 case CS4231_REC: 1979 dir = DDI_DMA_READ; 1980 caps = ENGINE_INPUT_CAP; 1981 eng->ce_syncdir = DDI_DMA_SYNC_FORKERNEL; 1982 eng->ce_codec_en = INTC_CEN; 1983 break; 1984 case CS4231_PLAY: 1985 dir = DDI_DMA_WRITE; 1986 caps = ENGINE_OUTPUT_CAP; 1987 eng->ce_syncdir = DDI_DMA_SYNC_FORDEV; 1988 eng->ce_codec_en = INTC_PEN; 1989 break; 1990 default: 1991 kmem_free(eng, sizeof (*eng)); 1992 audio_dev_warn(adev, "bad engine number (%d)!", num); 1993 return (DDI_FAILURE); 1994 } 1995 state->cs_engines[num] = eng; 1996 1997 /* allocate dma handle */ 1998 rc = ddi_dma_alloc_handle(dip, CS4231_DMA_ATTR(state), DDI_DMA_SLEEP, 1999 NULL, &eng->ce_dmah); 2000 if (rc != DDI_SUCCESS) { 2001 audio_dev_warn(adev, "ddi_dma_alloc_handle failed: %d", rc); 2002 return (DDI_FAILURE); 2003 } 2004 /* allocate DMA buffer */ 2005 rc = ddi_dma_mem_alloc(eng->ce_dmah, CS4231_BUFSZ, &buf_attr, 2006 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &eng->ce_kaddr, 2007 &bufsz, &eng->ce_acch); 2008 if (rc == DDI_FAILURE) { 2009 audio_dev_warn(adev, "dma_mem_alloc failed"); 2010 return (DDI_FAILURE); 2011 } 2012 2013 /* bind DMA buffer */ 2014 rc = ddi_dma_addr_bind_handle(eng->ce_dmah, NULL, 2015 eng->ce_kaddr, CS4231_BUFSZ, dir | DDI_DMA_CONSISTENT, 2016 DDI_DMA_SLEEP, NULL, &dmac, &ccnt); 2017 if ((rc != DDI_DMA_MAPPED) || (ccnt != 1)) { 2018 audio_dev_warn(adev, 2019 "ddi_dma_addr_bind_handle failed: %d", rc); 2020 return (DDI_FAILURE); 2021 } 2022 2023 eng->ce_paddr = dmac.dmac_address; 2024 2025 eng->ce_engine = audio_engine_alloc(&audiocs_engine_ops, caps); 2026 if (eng->ce_engine == NULL) { 2027 audio_dev_warn(adev, "audio_engine_alloc failed"); 2028 return (DDI_FAILURE); 2029 } 2030 2031 audio_engine_set_private(eng->ce_engine, eng); 2032 audio_dev_add_engine(adev, eng->ce_engine); 2033 return (DDI_SUCCESS); 2034 } 2035 2036 /* 2037 * audiocs_free_engine() 2038 * 2039 * Description: 2040 * This routine fress the engine and all associated resources. 2041 * 2042 * Arguments: 2043 * CS_engine_t *eng Engine to free. 2044 */ 2045 void 2046 audiocs_free_engine(CS_engine_t *eng) 2047 { 2048 CS_state_t *state = eng->ce_state; 2049 audio_dev_t *adev = state->cs_adev; 2050 2051 if (eng == NULL) 2052 return; 2053 if (eng->ce_engine) { 2054 audio_dev_remove_engine(adev, eng->ce_engine); 2055 audio_engine_free(eng->ce_engine); 2056 } 2057 if (eng->ce_paddr) { 2058 (void) ddi_dma_unbind_handle(eng->ce_dmah); 2059 } 2060 if (eng->ce_acch) { 2061 ddi_dma_mem_free(&eng->ce_acch); 2062 } 2063 if (eng->ce_dmah) { 2064 ddi_dma_free_handle(&eng->ce_dmah); 2065 } 2066 kmem_free(eng, sizeof (*eng)); 2067 } 2068 2069 /* 2070 * audiocs_poll_ready() 2071 * 2072 * Description: 2073 * This routine waits for the Codec to complete its initialization 2074 * sequence and is done with its autocalibration. 2075 * 2076 * Early versions of the Codec have a bug that can take as long as 2077 * 15 seconds to complete its initialization. For these cases we 2078 * use a timeout mechanism so we don't keep the machine locked up. 2079 * 2080 * Arguments: 2081 * CS_state_t *state The device's state structure 2082 * 2083 * Returns: 2084 * DDI_SUCCESS The Codec is ready to continue 2085 * DDI_FAILURE The Codec isn't ready to continue 2086 */ 2087 int 2088 audiocs_poll_ready(CS_state_t *state) 2089 { 2090 ddi_acc_handle_t handle = CODEC_HANDLE; 2091 int x = 0; 2092 uint8_t iar; 2093 uint8_t idr; 2094 2095 ASSERT(state->cs_regs != NULL); 2096 ASSERT(handle != NULL); 2097 2098 /* wait for the chip to initialize itself */ 2099 iar = ddi_get8(handle, &CS4231_IAR); 2100 2101 while ((iar & IAR_INIT) && x++ < CS4231_TIMEOUT) { 2102 drv_usecwait(50); 2103 iar = ddi_get8(handle, &CS4231_IAR); 2104 } 2105 2106 if (x >= CS4231_TIMEOUT) { 2107 return (DDI_FAILURE); 2108 } 2109 2110 x = 0; 2111 2112 /* 2113 * Now wait for the chip to complete its autocalibration. 2114 * Set the test register. 2115 */ 2116 SELIDX(state, ESI_REG); 2117 2118 idr = ddi_get8(handle, &CS4231_IDR); 2119 2120 while ((idr & ESI_ACI) && x++ < CS4231_TIMEOUT) { 2121 drv_usecwait(50); 2122 idr = ddi_get8(handle, &CS4231_IDR); 2123 } 2124 2125 if (x >= CS4231_TIMEOUT) { 2126 return (DDI_FAILURE); 2127 } 2128 2129 2130 return (DDI_SUCCESS); 2131 2132 } 2133 2134 /* 2135 * audiocs_sel_index() 2136 * 2137 * Description: 2138 * Select a cs4231 register. The cs4231 has a hardware bug where a 2139 * register is not always selected the first time. We try and try 2140 * again until the proper register is selected or we time out and 2141 * print an error message. 2142 * 2143 * Arguments: 2144 * audiohdl_t ahandle Handle to this device 2145 * ddi_acc_handle_t handle A handle to the device's registers 2146 * uint8_t addr The register address to program 2147 * int reg The register to select 2148 */ 2149 void 2150 #ifdef DEBUG 2151 audiocs_sel_index(CS_state_t *state, uint8_t reg, int n) 2152 #else 2153 audiocs_sel_index(CS_state_t *state, uint8_t reg) 2154 #endif 2155 { 2156 int x; 2157 uint8_t T; 2158 ddi_acc_handle_t handle = CODEC_HANDLE; 2159 uint8_t *addr = &CS4231_IAR; 2160 2161 for (x = 0; x < CS4231_RETRIES; x++) { 2162 ddi_put8(handle, addr, reg); 2163 T = ddi_get8(handle, addr); 2164 if (T == reg) { 2165 break; 2166 } 2167 drv_usecwait(1000); 2168 } 2169 2170 if (x == CS4231_RETRIES) { 2171 audio_dev_warn(state->cs_adev, 2172 #ifdef DEBUG 2173 "line %d: Couldn't select index (0x%02x 0x%02x)", n, 2174 #else 2175 "Couldn't select index (0x%02x 0x%02x)", 2176 #endif 2177 T, reg); 2178 audio_dev_warn(state->cs_adev, 2179 "audio may not work correctly until it is stopped and " 2180 "restarted"); 2181 } 2182 } 2183 2184 /* 2185 * audiocs_put_index() 2186 * 2187 * Description: 2188 * Program a cs4231 register. The cs4231 has a hardware bug where a 2189 * register is not programmed properly the first time. We program a value, 2190 * then immediately read back the value and reprogram if nescessary. 2191 * We do this until the register is properly programmed or we time out and 2192 * print an error message. 2193 * 2194 * Arguments: 2195 * CS_state_t state Handle to this device 2196 * uint8_t mask Mask to not set reserved register bits 2197 * int val The value to program 2198 */ 2199 void 2200 #ifdef DEBUG 2201 audiocs_put_index(CS_state_t *state, uint8_t val, uint8_t mask, int n) 2202 #else 2203 audiocs_put_index(CS_state_t *state, uint8_t val, uint8_t mask) 2204 #endif 2205 { 2206 int x; 2207 uint8_t T; 2208 ddi_acc_handle_t handle = CODEC_HANDLE; 2209 uint8_t *addr = &CS4231_IDR; 2210 2211 val &= mask; 2212 2213 for (x = 0; x < CS4231_RETRIES; x++) { 2214 ddi_put8(handle, addr, val); 2215 T = ddi_get8(handle, addr); 2216 if (T == val) { 2217 break; 2218 } 2219 drv_usecwait(1000); 2220 } 2221 2222 if (x == CS4231_RETRIES) { 2223 #ifdef DEBUG 2224 audio_dev_warn(state->cs_adev, 2225 "line %d: Couldn't set value (0x%02x 0x%02x)", n, T, val); 2226 #else 2227 audio_dev_warn(state->cs_adev, 2228 "Couldn't set value (0x%02x 0x%02x)", T, val); 2229 #endif 2230 audio_dev_warn(state->cs_adev, 2231 "audio may not work correctly until it is stopped and " 2232 "restarted"); 2233 } 2234 } 2235