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