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