audio_4231.c revision 9484:fbd5ddc28e96
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 */ 69static int audiocs_ddi_attach(dev_info_t *, ddi_attach_cmd_t); 70static int audiocs_ddi_detach(dev_info_t *, ddi_detach_cmd_t); 71static int audiocs_ddi_power(dev_info_t *, int, int); 72 73/* 74 * Entry point routine prototypes 75 */ 76static int audiocs_open(void *, int, unsigned *, unsigned *, caddr_t *); 77static void audiocs_close(void *); 78static int audiocs_start(void *); 79static void audiocs_stop(void *); 80static int audiocs_format(void *); 81static int audiocs_channels(void *); 82static int audiocs_rate(void *); 83static uint64_t audiocs_count(void *); 84static void audiocs_sync(void *, unsigned); 85static size_t audiocs_qlen(void *); 86 87/* 88 * Control callbacks. 89 */ 90static int audiocs_get_value(void *, uint64_t *); 91static int audiocs_set_ogain(void *, uint64_t); 92static int audiocs_set_igain(void *, uint64_t); 93static int audiocs_set_mgain(void *, uint64_t); 94static int audiocs_set_inputs(void *, uint64_t); 95static int audiocs_set_outputs(void *, uint64_t); 96static int audiocs_set_micboost(void *, uint64_t); 97 98/* Local Routines */ 99static int audiocs_resume(dev_info_t *); 100static int audiocs_attach(dev_info_t *); 101static int audiocs_detach(dev_info_t *); 102static int audiocs_suspend(dev_info_t *); 103 104static void audiocs_destroy(CS_state_t *); 105static int audiocs_init_state(CS_state_t *); 106static int audiocs_chip_init(CS_state_t *); 107static int audiocs_alloc_engine(CS_state_t *, int); 108static void audiocs_free_engine(CS_engine_t *); 109static void audiocs_reset_engine(CS_engine_t *); 110static int audiocs_start_engine(CS_engine_t *); 111static void audiocs_stop_engine(CS_engine_t *); 112static void audiocs_get_ports(CS_state_t *); 113static void audiocs_configure_input(CS_state_t *); 114static void audiocs_configure_output(CS_state_t *); 115static CS_ctrl_t *audiocs_alloc_ctrl(CS_state_t *, uint32_t, uint64_t); 116static void audiocs_free_ctrl(CS_ctrl_t *); 117static int audiocs_add_controls(CS_state_t *); 118static void audiocs_del_controls(CS_state_t *); 119static void audiocs_power_up(CS_state_t *); 120static void audiocs_power_down(CS_state_t *); 121static int audiocs_poll_ready(CS_state_t *); 122#ifdef DEBUG 123static void audiocs_put_index(CS_state_t *, uint8_t, uint8_t, int); 124static 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 128static void audiocs_put_index(CS_state_t *, uint8_t, uint8_t); 129static 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 143static 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 161static 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 173static 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 */ 186static 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 */ 250static 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 */ 266static 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 */ 273static 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 */ 291int 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 */ 314int 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 */ 338int 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 */ 361static int 362audiocs_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 */ 390static int 391audiocs_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 */ 419static int 420audiocs_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 465static void 466audiocs_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 */ 514static int 515audiocs_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 /* initialize the audio chip */ 553 if ((audiocs_chip_init(state)) == DDI_FAILURE) { 554 audio_dev_warn(adev, "chip_init() failed"); 555 goto error; 556 } 557 /* chip init will have powered us up */ 558 state->cs_powered = B_TRUE; 559 560 /* set up kernel statistics */ 561 if ((state->cs_ksp = kstat_create(ddi_driver_name(dip), 562 ddi_get_instance(dip), ddi_driver_name(dip), 563 "controller", KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT)) != NULL) { 564 kstat_install(state->cs_ksp); 565 } 566 567 /* we're ready, set up the interrupt handler */ 568 if (CS4231_DMA_ADD_INTR(state) != DDI_SUCCESS) { 569 goto error; 570 } 571 572 /* finally register with framework to kick everything off */ 573 if (audio_dev_register(state->cs_adev) != DDI_SUCCESS) { 574 audio_dev_warn(state->cs_adev, "unable to register audio dev"); 575 } 576 577 /* everything worked out, so report the device */ 578 ddi_report_dev(dip); 579 580 return (DDI_SUCCESS); 581 582error: 583 audiocs_destroy(state); 584 return (DDI_FAILURE); 585} 586 587/* 588 * audiocs_resume() 589 * 590 * Description: 591 * Resume a suspended device instance. 592 * 593 * Arguments: 594 * dev_info_t *dip Pointer to the device's dev_info struct 595 * 596 * Returns: 597 * DDI_SUCCESS The driver was initialized properly 598 * DDI_FAILURE The driver couldn't be initialized properly 599 */ 600static int 601audiocs_resume(dev_info_t *dip) 602{ 603 CS_state_t *state; 604 audio_dev_t *adev; 605 606 /* we've already allocated the state structure so get ptr */ 607 state = ddi_get_driver_private(dip); 608 adev = state->cs_adev; 609 610 ASSERT(dip == state->cs_dip); 611 ASSERT(!mutex_owned(&state->cs_lock)); 612 613 /* mark the Codec busy -- this should keep power(9e) away */ 614 (void) pm_busy_component(state->cs_dip, CS4231_COMPONENT); 615 616 /* power it up */ 617 audiocs_power_up(state); 618 state->cs_powered = B_TRUE; 619 620 /* initialize the audio chip */ 621 if ((audiocs_chip_init(state)) == DDI_FAILURE) { 622 audio_dev_warn(adev, "chip_init() failed"); 623 (void) pm_idle_component(state->cs_dip, CS4231_COMPONENT); 624 return (DDI_FAILURE); 625 } 626 627 mutex_enter(&state->cs_lock); 628 state->cs_suspended = B_FALSE; 629 630 /* restore mixer settings */ 631 audiocs_configure_output(state); 632 audiocs_configure_input(state); 633 634 for (int i = CS4231_PLAY; i <= CS4231_REC; i++) { 635 CS_engine_t *eng = state->cs_engines[i]; 636 637 audiocs_reset_engine(eng); 638 if (eng->ce_started) { 639 (void) audiocs_start_engine(eng); 640 } else { 641 audiocs_stop_engine(eng); 642 } 643 } 644 mutex_exit(&state->cs_lock); 645 646 /* 647 * We have already powered up the chip, but this alerts the 648 * framework to the fact. 649 */ 650 (void) pm_raise_power(dip, CS4231_COMPONENT, CS4231_PWR_ON); 651 (void) pm_idle_component(state->cs_dip, CS4231_COMPONENT); 652 653 return (DDI_SUCCESS); 654} 655 656/* 657 * audiocs_detach() 658 * 659 * Description: 660 * Detach an instance of the CS4231 driver. 661 * 662 * Arguments: 663 * dev_info_t *dip Pointer to the device's dev_info struct 664 * 665 * Returns: 666 * DDI_SUCCESS The driver was detached 667 * DDI_FAILURE The driver couldn't be detached (busy) 668 */ 669static int 670audiocs_detach(dev_info_t *dip) 671{ 672 CS_state_t *state; 673 audio_dev_t *adev; 674 ddi_acc_handle_t handle; 675 676 /* get the state structure */ 677 state = ddi_get_driver_private(dip); 678 handle = CODEC_HANDLE; 679 adev = state->cs_adev; 680 681 /* don't detach if still in use */ 682 if (audio_dev_unregister(adev) != DDI_SUCCESS) { 683 return (DDI_FAILURE); 684 } 685 686 if (state->cs_powered) { 687 /* 688 * Make sure the Codec and DMA engine are off. 689 */ 690 SELIDX(state, INTC_REG); 691 ANDIDX(state, ~(INTC_PEN|INTC_CEN), INTC_VALID_MASK); 692 693 /* make sure the DMA engine isn't going to do anything */ 694 CS4231_DMA_RESET(state); 695 696 /* 697 * power down the device, no reason to waste power without 698 * a driver 699 */ 700 (void) pm_lower_power(dip, CS4231_COMPONENT, CS4231_PWR_OFF); 701 } 702 703 audiocs_destroy(state); 704 705 return (DDI_SUCCESS); 706} 707 708/* 709 * audiocs_suspend() 710 * 711 * Description: 712 * Suspend an instance of the CS4231 driver. 713 * 714 * Arguments: 715 * dev_info_t *dip Pointer to the device's dev_info struct 716 * 717 * Returns: 718 * DDI_SUCCESS The driver was detached 719 * DDI_FAILURE The driver couldn't be detached 720 */ 721static int 722audiocs_suspend(dev_info_t *dip) 723{ 724 CS_state_t *state; 725 726 /* get the state structure */ 727 state = ddi_get_driver_private(dip); 728 729 ASSERT(!mutex_owned(&state->cs_lock)); 730 731 mutex_enter(&state->cs_lock); 732 733 ASSERT(!state->cs_suspended); 734 735 if (state->cs_powered) { 736 /* stop playing and recording */ 737 CS4231_DMA_STOP(state, state->cs_engines[CS4231_PLAY]); 738 CS4231_DMA_STOP(state, state->cs_engines[CS4231_REC]); 739 740 /* now we can power down the Codec */ 741 audiocs_power_down(state); 742 state->cs_powered = B_FALSE; 743 } 744 state->cs_suspended = B_TRUE; /* stop new ops */ 745 mutex_exit(&state->cs_lock); 746 747 ASSERT(!mutex_owned(&state->cs_lock)); 748 return (DDI_SUCCESS); 749} 750 751#define PLAYCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY) 752#define RECCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC) 753#define MONCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR) 754#define PCMVOL (PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL) 755#define MAINVOL (PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL) 756#define RECVOL (RECCTL | AUDIO_CTRL_FLAG_RECVOL) 757#define MONVOL (MONCTL | AUDIO_CTRL_FLAG_MONVOL) 758 759/* 760 * audiocs_alloc_ctrl 761 * 762 * Description: 763 * Allocates a control structure for the audio mixer. 764 * 765 * Arguments: 766 * CS_state_t *state Device soft state. 767 * uint32_t num Control number to allocate. 768 * uint64_t val Initial value. 769 * 770 * Returns: 771 * Pointer to newly allocated CS_ctrl_t structure. 772 */ 773static CS_ctrl_t * 774audiocs_alloc_ctrl(CS_state_t *state, uint32_t num, uint64_t val) 775{ 776 audio_ctrl_desc_t desc; 777 audio_ctrl_wr_t fn; 778 CS_ctrl_t *cc; 779 780 cc = kmem_zalloc(sizeof (*cc), KM_SLEEP); 781 cc->cc_state = state; 782 cc->cc_num = num; 783 784 bzero(&desc, sizeof (desc)); 785 786 switch (num) { 787 case CTL_VOLUME: 788 desc.acd_name = AUDIO_CTRL_ID_VOLUME; 789 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 790 desc.acd_minvalue = 0; 791 desc.acd_maxvalue = 100; 792 desc.acd_flags = PCMVOL; 793 fn = audiocs_set_ogain; 794 break; 795 796 case CTL_IGAIN: 797 desc.acd_name = AUDIO_CTRL_ID_RECGAIN; 798 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 799 desc.acd_minvalue = 0; 800 desc.acd_maxvalue = 100; 801 desc.acd_flags = RECVOL; 802 fn = audiocs_set_igain; 803 break; 804 805 case CTL_MGAIN: 806 desc.acd_name = AUDIO_CTRL_ID_MONGAIN; 807 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 808 desc.acd_minvalue = 0; 809 desc.acd_maxvalue = 100; 810 desc.acd_flags = MONVOL; 811 fn = audiocs_set_mgain; 812 break; 813 814 case CTL_INPUTS: 815 desc.acd_name = AUDIO_CTRL_ID_RECSRC; 816 desc.acd_type = AUDIO_CTRL_TYPE_ENUM; 817 desc.acd_minvalue = state->cs_imask; 818 desc.acd_maxvalue = state->cs_imask; 819 desc.acd_flags = RECCTL; 820 for (int i = 0; audiocs_inputs[i]; i++) { 821 desc.acd_enum[i] = audiocs_inputs[i]; 822 } 823 fn = audiocs_set_inputs; 824 825 break; 826 827 case CTL_OUTPUTS: 828 desc.acd_name = AUDIO_CTRL_ID_OUTPUTS; 829 desc.acd_type = AUDIO_CTRL_TYPE_ENUM; 830 desc.acd_minvalue = state->cs_omod; 831 desc.acd_maxvalue = state->cs_omask; 832 desc.acd_flags = PLAYCTL | AUDIO_CTRL_FLAG_MULTI; 833 for (int i = 0; audiocs_outputs[i]; i++) { 834 desc.acd_enum[i] = audiocs_outputs[i]; 835 } 836 fn = audiocs_set_outputs; 837 break; 838 839 case CTL_MICBOOST: 840 desc.acd_name = AUDIO_CTRL_ID_MICBOOST; 841 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN; 842 desc.acd_minvalue = 0; 843 desc.acd_maxvalue = 1; 844 desc.acd_flags = RECCTL; 845 fn = audiocs_set_micboost; 846 break; 847 } 848 849 cc->cc_val = val; 850 cc->cc_ctrl = audio_dev_add_control(state->cs_adev, &desc, 851 audiocs_get_value, fn, cc); 852 853 return (cc); 854} 855 856/* 857 * audiocs_free_ctrl 858 * 859 * Description: 860 * Frees a control and all resources associated with it. 861 * 862 * Arguments: 863 * CS_ctrl_t *cc Pointer to control structure. 864 */ 865static void 866audiocs_free_ctrl(CS_ctrl_t *cc) 867{ 868 if (cc == NULL) 869 return; 870 if (cc->cc_ctrl) 871 audio_dev_del_control(cc->cc_ctrl); 872 kmem_free(cc, sizeof (*cc)); 873} 874 875/* 876 * audiocs_add_controls 877 * 878 * Description: 879 * Allocates and registers all controls for this device. 880 * 881 * Arguments: 882 * CS_state_t *state Device soft state. 883 * 884 * Returns: 885 * DDI_SUCCESS All controls added and registered 886 * DDI_FAILURE At least one control was not added or registered. 887 */ 888static int 889audiocs_add_controls(CS_state_t *state) 890{ 891#define ADD_CTRL(CTL, ID, VAL) \ 892 state->cs_##CTL = audiocs_alloc_ctrl(state, ID, VAL); \ 893 if (state->cs_##CTL == NULL) { \ 894 audio_dev_warn(state->cs_adev, \ 895 "unable to allocate %s control", #ID); \ 896 return (DDI_FAILURE); \ 897 } 898 899 ADD_CTRL(ogain, CTL_VOLUME, 0x4b4b); 900 ADD_CTRL(igain, CTL_IGAIN, 0x3232); 901 ADD_CTRL(mgain, CTL_MGAIN, 0); 902 ADD_CTRL(micboost, CTL_MICBOOST, 0); 903 ADD_CTRL(outputs, CTL_OUTPUTS, (state->cs_omask & ~state->cs_omod) | 904 (1U << OUTPUT_SPEAKER)); 905 ADD_CTRL(inputs, CTL_INPUTS, (1U << INPUT_MIC)); 906 907 mutex_enter(&state->cs_lock); 908 audiocs_configure_output(state); 909 audiocs_configure_input(state); 910 mutex_exit(&state->cs_lock); 911 912 return (DDI_SUCCESS); 913} 914/* 915 * audiocs_del_controls 916 * 917 * Description: 918 * Unregisters and frees all controls for this device. 919 * 920 * Arguments: 921 * CS_state_t *state Device soft state. 922 */ 923void 924audiocs_del_controls(CS_state_t *state) 925{ 926 audiocs_free_ctrl(state->cs_ogain); 927 audiocs_free_ctrl(state->cs_igain); 928 audiocs_free_ctrl(state->cs_mgain); 929 audiocs_free_ctrl(state->cs_micboost); 930 audiocs_free_ctrl(state->cs_inputs); 931 audiocs_free_ctrl(state->cs_outputs); 932} 933 934 935/* 936 * audiocs_chip_init() 937 * 938 * Description: 939 * Power up the audio core, initialize the audio Codec, prepare the chip 940 * for use. 941 * 942 * Arguments: 943 * CS_state_t *state The device's state structure 944 * 945 * Returns: 946 * DDI_SUCCESS Chip initialized and ready to use 947 * DDI_FAILURE Chip not initialized and not ready 948 */ 949static int 950audiocs_chip_init(CS_state_t *state) 951{ 952 ddi_acc_handle_t handle = CODEC_HANDLE; 953 954 /* make sure we are powered up */ 955 CS4231_DMA_POWER(state, CS4231_PWR_ON); 956 957 CS4231_DMA_RESET(state); 958 959 /* activate registers 16 -> 31 */ 960 SELIDX(state, MID_REG); 961 ddi_put8(handle, &CS4231_IDR, MID_MODE2); 962 963 /* now figure out what version we have */ 964 SELIDX(state, VID_REG); 965 if (ddi_get8(handle, &CS4231_IDR) & VID_A) { 966 state->cs_revA = B_TRUE; 967 } else { 968 state->cs_revA = B_FALSE; 969 } 970 971 /* get rid of annoying popping by muting the output channels */ 972 SELIDX(state, LDACO_REG); 973 PUTIDX(state, LDACO_LDM | LDACO_MID_GAIN, LDAC0_VALID_MASK); 974 SELIDX(state, RDACO_REG); 975 PUTIDX(state, RDACO_RDM | RDACO_MID_GAIN, RDAC0_VALID_MASK); 976 977 /* initialize aux input channels to known gain values & muted */ 978 SELIDX(state, LAUX1_REG); 979 PUTIDX(state, LAUX1_LX1M | LAUX1_UNITY_GAIN, LAUX1_VALID_MASK); 980 SELIDX(state, RAUX1_REG); 981 PUTIDX(state, RAUX1_RX1M | RAUX1_UNITY_GAIN, RAUX1_VALID_MASK); 982 SELIDX(state, LAUX2_REG); 983 PUTIDX(state, LAUX2_LX2M | LAUX2_UNITY_GAIN, LAUX2_VALID_MASK); 984 SELIDX(state, RAUX2_REG); 985 PUTIDX(state, RAUX2_RX2M | RAUX2_UNITY_GAIN, RAUX2_VALID_MASK); 986 987 /* initialize aux input channels to known gain values & muted */ 988 SELIDX(state, LLIC_REG); 989 PUTIDX(state, LLIC_LLM | LLIC_UNITY_GAIN, LLIC_VALID_MASK); 990 SELIDX(state, RLIC_REG); 991 PUTIDX(state, RLIC_RLM | RLIC_UNITY_GAIN, RLIC_VALID_MASK); 992 993 /* program the sample rate, play and capture must be the same */ 994 SELIDX(state, FSDF_REG | IAR_MCE); 995 PUTIDX(state, FS_48000 | PDF_LINEAR16NE | PDF_STEREO, FSDF_VALID_MASK); 996 SELIDX(state, FSDF_REG); 997 SELIDX(state, CDF_REG | IAR_MCE); 998 PUTIDX(state, CDF_LINEAR16NE | CDF_STEREO, CDF_VALID_MASK); 999 SELIDX(state, CDF_REG); 1000 1001 /* 1002 * Set up the Codec for playback and capture disabled, dual DMA, and 1003 * playback and capture DMA. 1004 */ 1005 SELIDX(state, (INTC_REG | IAR_MCE)); 1006 PUTIDX(state, INTC_DDC | INTC_PDMA | INTC_CDMA, INTC_VALID_MASK); 1007 1008 /* turn off the MCE bit */ 1009 SELIDX(state, LADCI_REG); 1010 1011 /* wait for the Codec before we continue XXX - do we need this? */ 1012 if (audiocs_poll_ready(state) == DDI_FAILURE) { 1013 return (DDI_FAILURE); 1014 } 1015 1016 /* 1017 * Turn on the output level bit to be 2.8 Vpp. Also, don't go to 0 on 1018 * underflow. 1019 */ 1020 SELIDX(state, AFE1_REG); 1021 PUTIDX(state, AFE1_OLB, AFE1_VALID_MASK); 1022 1023 /* turn on the high pass filter if Rev A */ 1024 SELIDX(state, AFE2_REG); 1025 if (state->cs_revA) { 1026 PUTIDX(state, AFE2_HPF, AFE2_VALID_MASK); 1027 } else { 1028 PUTIDX(state, 0, AFE2_VALID_MASK); 1029 } 1030 1031 /* clear the play and capture interrupt flags */ 1032 SELIDX(state, AFS_REG); 1033 ddi_put8(handle, &CS4231_STATUS, (AFS_RESET_STATUS)); 1034 1035 /* the play and record gains will be set by the audio mixer */ 1036 1037 /* unmute the output */ 1038 SELIDX(state, LDACO_REG); 1039 ANDIDX(state, ~LDACO_LDM, LDAC0_VALID_MASK); 1040 SELIDX(state, RDACO_REG); 1041 ANDIDX(state, ~RDACO_RDM, RDAC0_VALID_MASK); 1042 1043 /* unmute the mono speaker and mute mono in */ 1044 SELIDX(state, MIOC_REG); 1045 PUTIDX(state, MIOC_MIM, MIOC_VALID_MASK); 1046 1047 /* clear the mode change bit */ 1048 SELIDX(state, RDACO_REG); 1049 1050 /* wait for the Codec before we continue XXX - do we need this? */ 1051 if (audiocs_poll_ready(state) == DDI_FAILURE) { 1052 return (DDI_FAILURE); 1053 } 1054 1055 return (DDI_SUCCESS); 1056} 1057 1058/* 1059 * audiocs_init_state() 1060 * 1061 * Description: 1062 * This routine initializes the audio driver's state structure and 1063 * maps in the registers. This also includes reading the properties. 1064 * 1065 * CAUTION: This routine maps the registers and initializes a mutex. 1066 * Failure cleanup is handled by cs4231_attach(). It is not 1067 * handled locally by this routine. 1068 * 1069 * Arguments: 1070 * CS_state_t *state The device's state structure 1071 * 1072 * Returns: 1073 * DDI_SUCCESS State structure initialized 1074 * DDI_FAILURE State structure not initialized 1075 */ 1076static int 1077audiocs_init_state(CS_state_t *state) 1078{ 1079 audio_dev_t *adev = state->cs_adev; 1080 dev_info_t *dip = state->cs_dip; 1081 char *prop_str; 1082 char *pm_comp[] = { 1083 "NAME=audiocs audio device", 1084 "0=off", 1085 "1=on" }; 1086 1087 /* set up the pm-components */ 1088 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, dip, 1089 "pm-components", pm_comp, 3) != DDI_PROP_SUCCESS) { 1090 audio_dev_warn(adev, "couldn't create pm-components property"); 1091 return (DDI_FAILURE); 1092 } 1093 1094 /* figure out which DMA engine hardware we have */ 1095 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1096 "dma-model", &prop_str) == DDI_PROP_SUCCESS) { 1097 if (strcmp(prop_str, "eb2dma") == 0) { 1098 state->cs_dma_engine = EB2_DMA; 1099 state->cs_dma_ops = &cs4231_eb2dma_ops; 1100 } else { 1101 state->cs_dma_engine = APC_DMA; 1102 state->cs_dma_ops = &cs4231_apcdma_ops; 1103 } 1104 ddi_prop_free(prop_str); 1105 } else { 1106 state->cs_dma_engine = APC_DMA; 1107 state->cs_dma_ops = &cs4231_apcdma_ops; 1108 } 1109 1110 /* cs_regs, cs_eb2_regs and cs_handles filled in later */ 1111 1112 /* most of what's left is filled in when the registers are mapped */ 1113 1114 audiocs_get_ports(state); 1115 1116 /* Allocate engines, must be done before register mapping called */ 1117 if ((audiocs_alloc_engine(state, CS4231_PLAY) != DDI_SUCCESS) || 1118 (audiocs_alloc_engine(state, CS4231_REC) != DDI_SUCCESS)) { 1119 return (DDI_FAILURE); 1120 } 1121 1122 /* Map in the registers */ 1123 if (CS4231_DMA_MAP_REGS(state) == DDI_FAILURE) { 1124 return (DDI_FAILURE); 1125 } 1126 1127 1128 /* Allocate and add controls, must be done *after* registers mapped */ 1129 if (audiocs_add_controls(state) != DDI_SUCCESS) { 1130 return (DDI_FAILURE); 1131 } 1132 1133 state->cs_suspended = B_FALSE; 1134 state->cs_powered = B_FALSE; 1135 1136 return (DDI_SUCCESS); 1137} 1138 1139/* 1140 * audiocs_get_ports() 1141 * 1142 * Description: 1143 * Get which audiocs h/w version we have and use this to 1144 * determine the input and output ports as well whether or not 1145 * the hardware has internal loopbacks or not. We also have three 1146 * different ways for the properties to be specified, which we 1147 * also need to worry about. 1148 * 1149 * Vers Platform(s) DMA eng. audio-module** loopback 1150 * a SS-4+/SS-5+ apcdma no no 1151 * b Ultra-1&2 apcdma no yes 1152 * c positron apcdma no yes 1153 * d PPC - retired 1154 * e x86 - retired 1155 * f tazmo eb2dma Perigee no 1156 * g tazmo eb2dma Quark yes 1157 * h darwin+ eb2dma no N/A 1158 * 1159 * Vers model~ aux1* aux2* 1160 * a N/A N/A N/A 1161 * b N/A N/A N/A 1162 * c N/A N/A N/A 1163 * d retired 1164 * e retired 1165 * f SUNW,CS4231f N/A N/A 1166 * g SUNW,CS4231g N/A N/A 1167 * h SUNW,CS4231h cdrom none 1168 * 1169 * * = Replaces internal-loopback for latest property type, can be 1170 * set to "cdrom", "loopback", or "none". 1171 * 1172 * ** = For plugin audio modules only. Starting with darwin, this 1173 * property is replaces by the model property. 1174 * 1175 * ~ = Replaces audio-module. 1176 * 1177 * + = Has the capability of having a cable run from the internal 1178 * CD-ROM to the audio device. 1179 * 1180 * N/A = Not applicable, the property wasn't created for early 1181 * platforms, or the property has been retired. 1182 * 1183 * NOTE: Older tazmo and quark machines don't have the model property. 1184 * 1185 * Arguments: 1186 * CS_state_t *state The device's state structure 1187 */ 1188static void 1189audiocs_get_ports(CS_state_t *state) 1190{ 1191 dev_info_t *dip = state->cs_dip; 1192 audio_dev_t *adev = state->cs_adev; 1193 char *prop_str; 1194 1195 /* First we set the common ports, etc. */ 1196 state->cs_omask = state->cs_omod = 1197 (1U << OUTPUT_SPEAKER) | 1198 (1U << OUTPUT_HEADPHONES) | 1199 (1U << OUTPUT_LINEOUT); 1200 state->cs_imask = 1201 (1U << INPUT_MIC) | 1202 (1U << INPUT_LINEIN) | 1203 (1U << INPUT_STEREOMIX); 1204 1205 /* now we try the new "model" property */ 1206 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1207 "model", &prop_str) == DDI_PROP_SUCCESS) { 1208 if (strcmp(prop_str, "SUNW,CS4231h") == 0) { 1209 /* darwin */ 1210 audio_dev_set_version(adev, CS_DEV_VERSION_H); 1211 state->cs_imask |= (1U << INPUT_CD); 1212 state->cs_omod = (1U << OUTPUT_SPEAKER); 1213 } else if (strcmp(prop_str, "SUNW,CS4231g") == 0) { 1214 /* quark audio module */ 1215 audio_dev_set_version(adev, CS_DEV_VERSION_G); 1216 /* 1217 * NB: This could do SUNVTS LOOPBACK, but we 1218 * don't support it for now... owing to no 1219 * support in framework. 1220 */ 1221 } else if (strcmp(prop_str, "SUNW,CS4231f") == 0) { 1222 /* tazmo */ 1223 audio_dev_set_version(adev, CS_DEV_VERSION_F); 1224 } else { 1225 audio_dev_set_version(adev, prop_str); 1226 audio_dev_warn(adev, 1227 "unknown audio model: %s, some parts of " 1228 "audio may not work correctly", prop_str); 1229 } 1230 ddi_prop_free(prop_str); /* done with the property */ 1231 } else { /* now try the older "audio-module" property */ 1232 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 1233 DDI_PROP_DONTPASS, "audio-module", &prop_str) == 1234 DDI_PROP_SUCCESS) { 1235 switch (*prop_str) { 1236 case 'Q': /* quark audio module */ 1237 audio_dev_set_version(adev, CS_DEV_VERSION_G); 1238 /* See quark comment above about SunVTS */ 1239 break; 1240 case 'P': /* tazmo */ 1241 audio_dev_set_version(adev, CS_DEV_VERSION_F); 1242 break; 1243 default: 1244 audio_dev_set_version(adev, prop_str); 1245 audio_dev_warn(adev, 1246 "unknown audio module: %s, some " 1247 "parts of audio may not work correctly", 1248 prop_str); 1249 break; 1250 } 1251 ddi_prop_free(prop_str); /* done with the prop */ 1252 } else { /* now try heuristics, ;-( */ 1253 if (ddi_prop_get_int(DDI_DEV_T_ANY, dip, 1254 DDI_PROP_DONTPASS, "internal-loopback", B_FALSE)) { 1255 if (state->cs_dma_engine == EB2_DMA) { 1256 audio_dev_set_version(adev, 1257 CS_DEV_VERSION_C); 1258 } else { 1259 audio_dev_set_version(adev, 1260 CS_DEV_VERSION_B); 1261 } 1262 /* 1263 * Again, we don't support SunVTS for these 1264 * boards, although we potentially could. 1265 */ 1266 } else { 1267 audio_dev_set_version(adev, CS_DEV_VERSION_A); 1268 state->cs_imask |= (1U << INPUT_CD); 1269 } 1270 } 1271 } 1272} 1273 1274/* 1275 * audiocs_power_up() 1276 * 1277 * Description: 1278 * Power up the Codec and restore the codec's registers. 1279 * 1280 * NOTE: We don't worry about locking since the only routines 1281 * that may call us are attach() and power() Both of 1282 * which should be the only threads in the driver. 1283 * 1284 * Arguments: 1285 * CS_state_t *state The device's state structure 1286 */ 1287static void 1288audiocs_power_up(CS_state_t *state) 1289{ 1290 ddi_acc_handle_t handle = CODEC_HANDLE; 1291 int i; 1292 1293 /* turn on the Codec */ 1294 CS4231_DMA_POWER(state, CS4231_PWR_ON); 1295 1296 /* reset the DMA engine(s) */ 1297 CS4231_DMA_RESET(state); 1298 1299 /* 1300 * Reload the Codec's registers, the DMA engines will be 1301 * taken care of when play and record start up again. But 1302 * first enable registers 16 -> 31. 1303 */ 1304 SELIDX(state, MID_REG); 1305 PUTIDX(state, state->cs_save[MID_REG], MID_VALID_MASK); 1306 1307 for (i = 0; i < CS4231_REGS; i++) { 1308 /* restore Codec registers */ 1309 SELIDX(state, (i | IAR_MCE)); 1310 ddi_put8(handle, &CS4231_IDR, state->cs_save[i]); 1311 drv_usecwait(500); /* chip bug */ 1312 } 1313 /* clear MCE bit */ 1314 SELIDX(state, 0); 1315} 1316 1317/* 1318 * audiocs_power_down() 1319 * 1320 * Description: 1321 * Power down the Codec and save the codec's registers. 1322 * 1323 * NOTE: See the note in cs4231_power_up() about locking. 1324 * 1325 * Arguments: 1326 * CS_state_t *state The device's state structure 1327 */ 1328static void 1329audiocs_power_down(CS_state_t *state) 1330{ 1331 ddi_acc_handle_t handle; 1332 int i; 1333 1334 handle = state->cs_handles.cs_codec_hndl; 1335 1336 /* 1337 * We are powering down, so we don't need to do a thing with 1338 * the DMA engines. However, we do need to save the Codec 1339 * registers. 1340 */ 1341 1342 for (i = 0; i < CS4231_REGS; i++) { 1343 /* save Codec regs */ 1344 SELIDX(state, i); 1345 state->cs_save[i] = ddi_get8(handle, &CS4231_IDR); 1346 } 1347 1348 /* turn off the Codec */ 1349 CS4231_DMA_POWER(state, CS4231_PWR_OFF); 1350 1351} /* cs4231_power_down() */ 1352 1353/* 1354 * audiocs_configure_input() 1355 * 1356 * Description: 1357 * Configure input properties of the mixer (e.g. igain, ports). 1358 * 1359 * Arguments: 1360 * CS_state_t *state The device's state structure 1361 */ 1362static void 1363audiocs_configure_input(CS_state_t *state) 1364{ 1365 uint8_t l, r; 1366 uint64_t inputs; 1367 uint64_t micboost; 1368 1369 ASSERT(mutex_owned(&state->cs_lock)); 1370 1371 if (state->cs_suspended) 1372 return; 1373 1374 inputs = state->cs_inputs->cc_val; 1375 micboost = state->cs_micboost->cc_val; 1376 r = (state->cs_igain->cc_val & 0xff); 1377 l = ((state->cs_igain->cc_val & 0xff00) >> 8); 1378 1379 /* rescale these for our atten array */ 1380 l = (((uint32_t)l * 255) / 100) & 0xff; 1381 r = (((uint32_t)r * 255) / 100) & 0xff; 1382 1383 /* we downshift by 4 bits -- igain only has 16 possible values */ 1384 /* NB: that we do not scale here! The SADA driver didn't do so. */ 1385 l = l >> 4; 1386 r = r >> 4; 1387 1388 if (inputs & (1U << INPUT_MIC)) { 1389 l |= LADCI_LMIC; 1390 r |= RADCI_RMIC; 1391 } 1392 if (inputs & (1U << INPUT_LINEIN)) { 1393 l |= LADCI_LLINE; 1394 r |= RADCI_RLINE; 1395 } 1396 if (inputs & (1U << INPUT_CD)) { 1397 /* note that SunVTS also uses this */ 1398 l |= LADCI_LAUX1; 1399 r |= RADCI_RAUX1; 1400 } 1401 if (inputs & (1U << INPUT_STEREOMIX)) { 1402 l |= LADCI_LLOOP; 1403 r |= RADCI_RLOOP; 1404 } 1405 if (micboost) { 1406 l |= LADCI_LMGE; 1407 r |= RADCI_RMGE; 1408 } 1409 1410 SELIDX(state, LADCI_REG); 1411 PUTIDX(state, l, LADCI_VALID_MASK); 1412 1413 SELIDX(state, RADCI_REG); 1414 PUTIDX(state, r, RADCI_VALID_MASK); 1415} 1416 1417/* 1418 * audiocs_configure_output() 1419 * 1420 * Description: 1421 * Configure output properties of the mixer (e.g. ogain, mgain). 1422 * 1423 * Arguments: 1424 * CS_state_t *state The device's state structure 1425 */ 1426static void 1427audiocs_configure_output(CS_state_t *state) 1428{ 1429 uint64_t outputs; 1430 uint8_t l, r; 1431 uint8_t rmute, lmute; 1432 uint8_t mgain; 1433 ddi_acc_handle_t handle = CODEC_HANDLE; 1434 1435 rmute = lmute = 0; 1436 1437 ASSERT(mutex_owned(&state->cs_lock)); 1438 1439 if (state->cs_suspended) 1440 return; 1441 1442 outputs = state->cs_outputs->cc_val; 1443 1444 /* port selection */ 1445 SELIDX(state, MIOC_REG); 1446 if (outputs & (1U << OUTPUT_SPEAKER)) { 1447 ANDIDX(state, ~MIOC_MONO_SPKR_MUTE, MIOC_VALID_MASK); 1448 } else { 1449 ORIDX(state, MIOC_MONO_SPKR_MUTE, MIOC_VALID_MASK); 1450 } 1451 SELIDX(state, PC_REG); 1452 if (outputs & (1U << OUTPUT_HEADPHONES)) { 1453 ANDIDX(state, ~PC_HEADPHONE_MUTE, PC_VALID_MASK); 1454 } else { 1455 ORIDX(state, PC_HEADPHONE_MUTE, PC_VALID_MASK); 1456 } 1457 SELIDX(state, PC_REG); 1458 if (outputs & (1U << OUTPUT_LINEOUT)) { 1459 ANDIDX(state, ~PC_LINE_OUT_MUTE, PC_VALID_MASK); 1460 } else { 1461 ORIDX(state, PC_LINE_OUT_MUTE, PC_VALID_MASK); 1462 } 1463 1464 /* monitor gain */ 1465 mgain = cs4231_atten[((state->cs_mgain->cc_val * 255) / 100) & 0xff]; 1466 SELIDX(state, LC_REG); 1467 if (mgain == 0) { 1468 /* disable loopbacks when gain == 0 */ 1469 PUTIDX(state, LC_OFF, LC_VALID_MASK); 1470 } else { 1471 /* we use cs4231_atten[] to linearize attenuation */ 1472 PUTIDX(state, (mgain << 2) | LC_LBE, LC_VALID_MASK); 1473 } 1474 1475 /* output gain */ 1476 l = ((state->cs_ogain->cc_val >> 8) & 0xff); 1477 r = (state->cs_ogain->cc_val & 0xff); 1478 if (l == 0) { 1479 lmute = LDACO_LDM; 1480 } 1481 if (r == 0) { 1482 rmute = RDACO_RDM; 1483 } 1484 1485 /* rescale these for our atten array */ 1486 l = cs4231_atten[(((uint32_t)l * 255) / 100) & 0xff] | lmute; 1487 r = cs4231_atten[(((uint32_t)r * 255) / 100) & 0xff] | rmute; 1488 1489 SELIDX(state, LDACO_REG); 1490 PUTIDX(state, l, LDAC0_VALID_MASK); 1491 SELIDX(state, RDACO_REG); 1492 PUTIDX(state, r, RDAC0_VALID_MASK); 1493} 1494 1495/* 1496 * audiocs_get_value() 1497 * 1498 * Description: 1499 * Get a control value 1500 * 1501 * Arguments: 1502 * void *arg The device's state structure 1503 * uint64_t *valp Pointer to store value. 1504 * 1505 * Returns: 1506 * 0 The Codec parameter has been retrieved. 1507 */ 1508static int 1509audiocs_get_value(void *arg, uint64_t *valp) 1510{ 1511 CS_ctrl_t *cc = arg; 1512 CS_state_t *state = cc->cc_state; 1513 1514 mutex_enter(&state->cs_lock); 1515 *valp = cc->cc_val; 1516 mutex_exit(&state->cs_lock); 1517 return (0); 1518} 1519 1520 1521/* 1522 * audiocs_set_ogain() 1523 * 1524 * Description: 1525 * Set the play gain. 1526 * 1527 * Arguments: 1528 * void *arg The device's state structure 1529 * uint64_t val The gain to set (both left and right) 1530 * 1531 * Returns: 1532 * 0 The Codec parameter has been set 1533 */ 1534static int 1535audiocs_set_ogain(void *arg, uint64_t val) 1536{ 1537 CS_ctrl_t *cc = arg; 1538 CS_state_t *state = cc->cc_state; 1539 1540 if ((val & ~0xffff) || 1541 ((val & 0xff) > 100) || 1542 (((val & 0xff00) >> 8) > 100)) 1543 return (EINVAL); 1544 1545 mutex_enter(&state->cs_lock); 1546 cc->cc_val = val; 1547 audiocs_configure_output(state); 1548 mutex_exit(&state->cs_lock); 1549 return (0); 1550} 1551 1552/* 1553 * audiocs_set_micboost() 1554 * 1555 * Description: 1556 * Set the 20 dB microphone boost. 1557 * 1558 * Arguments: 1559 * void *arg The device's state structure 1560 * uint64_t val The 1 to enable, 0 to disable. 1561 * 1562 * Returns: 1563 * 0 The Codec parameter has been set 1564 */ 1565static int 1566audiocs_set_micboost(void *arg, uint64_t val) 1567{ 1568 CS_ctrl_t *cc = arg; 1569 CS_state_t *state = cc->cc_state; 1570 1571 mutex_enter(&state->cs_lock); 1572 cc->cc_val = val ? B_TRUE : B_FALSE; 1573 audiocs_configure_input(state); 1574 mutex_exit(&state->cs_lock); 1575 return (0); 1576} 1577 1578/* 1579 * audiocs_set_igain() 1580 * 1581 * Description: 1582 * Set the record gain. 1583 * 1584 * Arguments: 1585 * void *arg The device's state structure 1586 * uint64_t val The gain to set (both left and right) 1587 * 1588 * Returns: 1589 * 0 The Codec parameter has been set 1590 */ 1591static int 1592audiocs_set_igain(void *arg, uint64_t val) 1593{ 1594 CS_ctrl_t *cc = arg; 1595 CS_state_t *state = cc->cc_state; 1596 1597 if ((val & ~0xffff) || 1598 ((val & 0xff) > 100) || 1599 (((val & 0xff00) >> 8) > 100)) 1600 return (EINVAL); 1601 1602 mutex_enter(&state->cs_lock); 1603 cc->cc_val = val; 1604 audiocs_configure_input(state); 1605 mutex_exit(&state->cs_lock); 1606 1607 return (0); 1608} 1609 1610/* 1611 * audiocs_set_inputs() 1612 * 1613 * Description: 1614 * Set the input ports. 1615 * 1616 * Arguments: 1617 * void *arg The device's state structure 1618 * uint64_t val The mask of output ports. 1619 * 1620 * Returns: 1621 * 0 The Codec parameter has been set 1622 */ 1623static int 1624audiocs_set_inputs(void *arg, uint64_t val) 1625{ 1626 CS_ctrl_t *cc = arg; 1627 CS_state_t *state = cc->cc_state; 1628 1629 if (val & ~(state->cs_imask)) 1630 return (EINVAL); 1631 1632 mutex_enter(&state->cs_lock); 1633 cc->cc_val = val; 1634 audiocs_configure_input(state); 1635 mutex_exit(&state->cs_lock); 1636 1637 return (0); 1638} 1639 1640/* 1641 * audiocs_set_outputs() 1642 * 1643 * Description: 1644 * Set the output ports. 1645 * 1646 * Arguments: 1647 * void *arg The device's state structure 1648 * uint64_t val The mask of input ports. 1649 * 1650 * Returns: 1651 * 0 The Codec parameter has been set 1652 */ 1653static int 1654audiocs_set_outputs(void *arg, uint64_t val) 1655{ 1656 CS_ctrl_t *cc = arg; 1657 CS_state_t *state = cc->cc_state; 1658 1659 if ((val & ~(state->cs_omod)) != 1660 (state->cs_omask & ~state->cs_omod)) 1661 return (EINVAL); 1662 1663 mutex_enter(&state->cs_lock); 1664 cc->cc_val = val; 1665 audiocs_configure_output(state); 1666 mutex_exit(&state->cs_lock); 1667 1668 return (0); 1669} 1670 1671/* 1672 * audiocs_set_mgain() 1673 * 1674 * Description: 1675 * Set the monitor gain. 1676 * 1677 * Arguments: 1678 * void *arg The device's state structure 1679 * uint64_t val The gain to set (monoaural).) 1680 * 1681 * Returns: 1682 * 0 The Codec parameter has been set 1683 */ 1684static int 1685audiocs_set_mgain(void *arg, uint64_t gain) 1686{ 1687 CS_ctrl_t *cc = arg; 1688 CS_state_t *state = cc->cc_state; 1689 1690 if (gain > 100) 1691 return (EINVAL); 1692 1693 mutex_enter(&state->cs_lock); 1694 cc->cc_val = gain; 1695 audiocs_configure_output(state); 1696 mutex_exit(&state->cs_lock); 1697 1698 return (0); 1699} 1700 1701/* 1702 * audiocs_open() 1703 * 1704 * Description: 1705 * Opens a DMA engine for use. 1706 * 1707 * Arguments: 1708 * void *arg The DMA engine to set up 1709 * int flag Open flags 1710 * unsigned *fragfrp Receives number of frames per fragment 1711 * unsigned *nfragsp Receives number of fragments 1712 * caddr_t *bufp Receives kernel data buffer 1713 * 1714 * Returns: 1715 * 0 on success 1716 * errno on failure 1717 */ 1718static int 1719audiocs_open(void *arg, int flag, 1720 unsigned *fragfrp, unsigned *nfragsp, caddr_t *bufp) 1721{ 1722 CS_engine_t *eng = arg; 1723 CS_state_t *state = eng->ce_state; 1724 dev_info_t *dip = state->cs_dip; 1725 1726 _NOTE(ARGUNUSED(flag)); 1727 1728 (void) pm_busy_component(dip, CS4231_COMPONENT); 1729 if (pm_raise_power(dip, CS4231_COMPONENT, CS4231_PWR_ON) == 1730 DDI_FAILURE) { 1731 1732 /* match the busy call above */ 1733 (void) pm_idle_component(dip, CS4231_COMPONENT); 1734 1735 audio_dev_warn(state->cs_adev, "power up failed"); 1736 } 1737 1738 eng->ce_started = B_FALSE; 1739 eng->ce_count = 0; 1740 1741 *fragfrp = eng->ce_fragfr; 1742 *nfragsp = CS4231_NFRAGS; 1743 *bufp = eng->ce_kaddr; 1744 1745 mutex_enter(&state->cs_lock); 1746 audiocs_reset_engine(eng); 1747 mutex_exit(&state->cs_lock); 1748 return (0); 1749} 1750 1751/* 1752 * audiocs_close() 1753 * 1754 * Description: 1755 * Closes an audio DMA engine that was previously opened. Since 1756 * nobody is using it, we take this opportunity to possibly power 1757 * down the entire device. 1758 * 1759 * Arguments: 1760 * void *arg The DMA engine to shut down 1761 */ 1762static void 1763audiocs_close(void *arg) 1764{ 1765 CS_engine_t *eng = arg; 1766 CS_state_t *state = eng->ce_state; 1767 1768 mutex_enter(&state->cs_lock); 1769 audiocs_stop_engine(eng); 1770 eng->ce_started = B_FALSE; 1771 mutex_exit(&state->cs_lock); 1772 1773 (void) pm_idle_component(state->cs_dip, CS4231_COMPONENT); 1774} 1775 1776/* 1777 * audiocs_stop() 1778 * 1779 * Description: 1780 * This is called by the framework to stop an engine that is 1781 * transferring data. 1782 * 1783 * Arguments: 1784 * void *arg The DMA engine to stop 1785 */ 1786static void 1787audiocs_stop(void *arg) 1788{ 1789 CS_engine_t *eng = arg; 1790 CS_state_t *state = eng->ce_state; 1791 1792 mutex_enter(&state->cs_lock); 1793 if (eng->ce_started) { 1794 audiocs_stop_engine(eng); 1795 eng->ce_started = B_FALSE; 1796 } 1797 mutex_exit(&state->cs_lock); 1798} 1799 1800/* 1801 * audiocs_start() 1802 * 1803 * Description: 1804 * This is called by the framework to start an engine transferring data. 1805 * 1806 * Arguments: 1807 * void *arg The DMA engine to start 1808 * 1809 * Returns: 1810 * 0 on success, an errno otherwise 1811 */ 1812static int 1813audiocs_start(void *arg) 1814{ 1815 CS_engine_t *eng = arg; 1816 CS_state_t *state = eng->ce_state; 1817 int rv = 0; 1818 1819 mutex_enter(&state->cs_lock); 1820 if (!eng->ce_started) { 1821 if (audiocs_start_engine(eng) == DDI_SUCCESS) { 1822 eng->ce_started = B_TRUE; 1823 } else { 1824 rv = EIO; 1825 } 1826 } 1827 mutex_exit(&state->cs_lock); 1828 return (rv); 1829} 1830 1831/* 1832 * audiocs_format() 1833 * 1834 * Description: 1835 * Called by the framework to query the format of the device. 1836 * 1837 * Arguments: 1838 * void *arg The DMA engine to query 1839 * 1840 * Returns: 1841 * AUDIO_FORMAT_S16_NE 1842 */ 1843static int 1844audiocs_format(void *arg) 1845{ 1846 _NOTE(ARGUNUSED(arg)); 1847 1848 return (AUDIO_FORMAT_S16_NE); 1849} 1850 1851/* 1852 * audiocs_channels() 1853 * 1854 * Description: 1855 * Called by the framework to query the channels of the device. 1856 * 1857 * Arguments: 1858 * void *arg The DMA engine to query 1859 * 1860 * Returns: 1861 * 2 (stereo) 1862 */ 1863static int 1864audiocs_channels(void *arg) 1865{ 1866 _NOTE(ARGUNUSED(arg)); 1867 1868 return (2); 1869} 1870 1871/* 1872 * audiocs_rates() 1873 * 1874 * Description: 1875 * Called by the framework to query the sample rate of the device. 1876 * 1877 * Arguments: 1878 * void *arg The DMA engine to query 1879 * 1880 * Returns: 1881 * 48000 1882 */ 1883static int 1884audiocs_rate(void *arg) 1885{ 1886 _NOTE(ARGUNUSED(arg)); 1887 1888 return (48000); 1889} 1890 1891/* 1892 * audiocs_count() 1893 * 1894 * Description: 1895 * This is called by the framework to get the engine's frame counter 1896 * 1897 * Arguments: 1898 * void *arg The DMA engine to query 1899 * 1900 * Returns: 1901 * frame count for current engine 1902 */ 1903static uint64_t 1904audiocs_count(void *arg) 1905{ 1906 CS_engine_t *eng = arg; 1907 CS_state_t *state = eng->ce_state; 1908 uint64_t val; 1909 1910 mutex_enter(&state->cs_lock); 1911 val = eng->ce_count; 1912 mutex_exit(&state->cs_lock); 1913 1914 return (val); 1915} 1916 1917/* 1918 * audiocs_sync() 1919 * 1920 * Description: 1921 * This is called by the framework to synchronize DMA caches. 1922 * 1923 * Arguments: 1924 * void *arg The DMA engine to sync 1925 */ 1926static void 1927audiocs_sync(void *arg, unsigned nframes) 1928{ 1929 CS_engine_t *eng = arg; 1930 _NOTE(ARGUNUSED(nframes)); 1931 1932 (void) ddi_dma_sync(eng->ce_dmah, 0, 0, eng->ce_syncdir); 1933} 1934 1935/* 1936 * audiocs_qlen() 1937 * 1938 * Description: 1939 * This is called by the framework to determine on-device queue length. 1940 * 1941 * Arguments: 1942 * void *arg The DMA engine to query 1943 * 1944 * Returns: 1945 * hardware queue length not reported by count (0 for this device) 1946 */ 1947static size_t 1948audiocs_qlen(void *arg) 1949{ 1950 CS_engine_t *eng = arg; 1951 1952 return (eng->ce_fragfr); 1953} 1954 1955 1956/* 1957 * audiocs_reset_engine() 1958 * 1959 * Description: 1960 * This routine resets the DMA engine pareparing it for work. 1961 * 1962 * Arguments: 1963 * CS_engine_t *engine DMA engine to stop. 1964 */ 1965void 1966audiocs_reset_engine(CS_engine_t *eng) 1967{ 1968 CS_state_t *state = eng->ce_state; 1969 uint8_t mask; 1970 uint8_t value; 1971 uint8_t reg; 1972 1973 if (eng->ce_num == CS4231_PLAY) { 1974 /* sample rate only set on play side */ 1975 value = FS_48000 | PDF_STEREO | PDF_LINEAR16NE; 1976 reg = FSDF_REG; 1977 mask = FSDF_VALID_MASK; 1978 } else { 1979 value = CDF_STEREO | CDF_LINEAR16NE; 1980 reg = CDF_REG; 1981 mask = CDF_VALID_MASK; 1982 } 1983 1984 SELIDX(state, reg | IAR_MCE); 1985 PUTIDX(state, value, mask); 1986 1987 (void) audiocs_poll_ready(state); 1988 1989 /* clear the mode change bit */ 1990 SELIDX(state, reg); 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 */ 2007int 2008audiocs_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 */ 2134void 2135audiocs_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 */ 2171int 2172audiocs_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 */ 2209void 2210audiocs_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 */ 2253int 2254audiocs_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 */ 2318void 2319#ifdef DEBUG 2320audiocs_sel_index(CS_state_t *state, uint8_t reg, int n) 2321#else 2322audiocs_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 */ 2371void 2372#ifdef DEBUG 2373audiocs_put_index(CS_state_t *state, uint8_t val, uint8_t mask, int n) 2374#else 2375audiocs_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