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 * Purpose: Driver for CMEDIA CM8738 PCI audio controller. 27 */ 28 /* 29 * This file is part of Open Sound System 30 * 31 * Copyright (C) 4Front Technologies 1996-2008. 32 */ 33 34 #include <sys/audio/audio_driver.h> 35 #include <sys/note.h> 36 #include <sys/pci.h> 37 #include <sys/sysmacros.h> 38 #include "audiocmi.h" 39 40 /* 41 * Note: The original 4Front driver had support SPDIF and dual dac 42 * options. Dual dac support is probably not terribly useful. SPDIF 43 * on the other hand might be quite useful, we just don't have a card 44 * that supports it at present. Some variants of the chip are also 45 * capable of jack retasking, but we're electing to punt on supporting 46 * that as well, for now (we don't have any cards that would benefit 47 * from this feature.) 48 * 49 * Note that surround support requires the use of the second DMA 50 * engine, and that the same second DMA engine is the only way one can 51 * capture from SPDIF. Rather than support a lot more complexity in 52 * the driver, we we will probably just punt on ever supporting 53 * capture of SPDIF. (SPDIF playback should be doable, however.) 54 * 55 * Adding back support for the advanced features would be an 56 * interesting project for someone with access to suitable hardware. 57 * 58 * Note that each variant (CMI 8338, 8738-033, -037, -055, and 8768) 59 * seems to have significant differences in some of the registers. 60 * While programming these parts for basic stereo is pretty much the 61 * same on all parts, doing anything more than that can be 62 * sigificantly different for each part. 63 */ 64 65 static ddi_device_acc_attr_t acc_attr = { 66 DDI_DEVICE_ATTR_V0, 67 DDI_STRUCTURE_LE_ACC, 68 DDI_STRICTORDER_ACC 69 }; 70 71 static ddi_device_acc_attr_t buf_attr = { 72 DDI_DEVICE_ATTR_V0, 73 DDI_NEVERSWAP_ACC, 74 DDI_STRICTORDER_ACC 75 }; 76 77 static ddi_dma_attr_t dma_attr = { 78 DMA_ATTR_VERSION, /* dma_attr_version */ 79 0x0, /* dma_attr_addr_lo */ 80 0xffffffffU, /* dma_attr_addr_hi */ 81 0x3ffff, /* dma_attr_count_max */ 82 0x8, /* dma_attr_align */ 83 0x7f, /* dma_attr_burstsizes */ 84 0x1, /* dma_attr_minxfer */ 85 0x3ffff, /* dma_attr_maxxfer */ 86 0x3ffff, /* dma_attr_seg */ 87 0x1, /* dma_attr_sgllen */ 88 0x1, /* dma_attr_granular */ 89 0 /* dma_attr_flags */ 90 }; 91 92 static uint_t 93 cmpci_intr(caddr_t arg1, caddr_t arg2) 94 { 95 cmpci_dev_t *dev = (void *)arg1; 96 97 uint32_t intstat, intctrl, intclear; 98 void (*cb0)(audio_engine_t *) = NULL; 99 void (*cb1)(audio_engine_t *) = NULL; 100 uint_t rv; 101 102 _NOTE(ARGUNUSED(arg2)); 103 104 rv = DDI_INTR_UNCLAIMED; 105 106 mutex_enter(&dev->mutex); 107 if (dev->suspended) { 108 mutex_exit(&dev->mutex); 109 return (rv); 110 } 111 112 intclear = 0; 113 intstat = GET32(dev, REG_INTSTAT); 114 intctrl = GET32(dev, REG_INTCTRL); 115 if ((intstat & INTSTAT_CH0_INT) && (intctrl & INTCTRL_CH0_EN)) { 116 intclear |= INTCTRL_CH0_EN; 117 cb0 = dev->port[0].callb; 118 } 119 if ((intstat & INTSTAT_CH1_INT) && (intctrl & INTCTRL_CH1_EN)) { 120 intclear |= INTCTRL_CH1_EN; 121 cb1 = dev->port[1].callb; 122 } 123 124 /* toggle the bits that we are going to handle */ 125 if (intclear) { 126 CLR32(dev, REG_INTCTRL, intclear); 127 SET32(dev, REG_INTCTRL, intclear); 128 rv = DDI_INTR_CLAIMED; 129 130 KSINTR(dev)->intrs[KSTAT_INTR_HARD]++; 131 } 132 133 mutex_exit(&dev->mutex); 134 135 if (cb0) { 136 (*cb0)(dev->port[0].engine); 137 } 138 if (cb1) { 139 (*cb1)(dev->port[1].engine); 140 } 141 142 return (rv); 143 } 144 145 static void 146 cmpci_reset_port(cmpci_port_t *port) 147 { 148 cmpci_dev_t *dev = port->dev; 149 150 if (dev->suspended) 151 return; 152 153 port->offset = 0; 154 155 /* reset channel */ 156 SET32(dev, REG_FUNCTRL0, port->fc0_rst_bit); 157 drv_usecwait(10); 158 CLR32(dev, REG_FUNCTRL0, port->fc0_rst_bit); 159 drv_usecwait(10); 160 161 /* Set 48k 16-bit stereo -- these are just with all bits set. */ 162 SET32(dev, REG_FUNCTRL1, port->fc1_rate_mask); 163 SET32(dev, REG_CHFORMAT, port->chformat_mask); 164 165 if ((port->num == 1) && (dev->maxch > 2)) { 166 CLR32(dev, REG_LEGACY, LEGACY_NXCHG); 167 168 if (port->nchan > 2) { 169 SET32(dev, REG_MISC, MISC_XCHGDAC); 170 CLR32(dev, REG_MISC, MISC_N4SPK3D); 171 } else { 172 CLR32(dev, REG_MISC, MISC_XCHGDAC); 173 SET32(dev, REG_MISC, MISC_N4SPK3D); 174 } 175 176 switch (port->nchan) { 177 case 2: 178 if (dev->maxch >= 8) { 179 CLR8(dev, REG_MISC2, MISC2_CHB3D8C); 180 } 181 if (dev->maxch >= 6) { 182 CLR32(dev, REG_CHFORMAT, CHFORMAT_CHB3D5C); 183 CLR32(dev, REG_LEGACY, LEGACY_CHB3D6C); 184 } 185 if (dev->maxch >= 4) { 186 CLR32(dev, REG_CHFORMAT, CHFORMAT_CHB3D); 187 } 188 break; 189 case 4: 190 if (dev->maxch >= 8) { 191 CLR8(dev, REG_MISC2, MISC2_CHB3D8C); 192 } 193 if (dev->maxch >= 6) { 194 CLR32(dev, REG_CHFORMAT, CHFORMAT_CHB3D5C); 195 CLR32(dev, REG_LEGACY, LEGACY_CHB3D6C); 196 CLR32(dev, REG_MISC, MISC_ENCENTER); 197 CLR32(dev, REG_LEGACY, LEGACY_EXBASSEN); 198 } 199 SET32(dev, REG_CHFORMAT, CHFORMAT_CHB3D); 200 break; 201 case 6: 202 if (dev->maxch >= 8) { 203 CLR8(dev, REG_MISC2, MISC2_CHB3D8C); 204 } 205 SET32(dev, REG_CHFORMAT, CHFORMAT_CHB3D5C); 206 SET32(dev, REG_LEGACY, LEGACY_CHB3D6C); 207 CLR32(dev, REG_MISC, MISC_ENCENTER); 208 CLR32(dev, REG_LEGACY, LEGACY_EXBASSEN); 209 CLR32(dev, REG_CHFORMAT, CHFORMAT_CHB3D); 210 break; 211 212 case 8: 213 SET8(dev, REG_MISC2, MISC2_CHB3D8C); 214 CLR32(dev, REG_MISC, MISC_ENCENTER); 215 CLR32(dev, REG_LEGACY, LEGACY_EXBASSEN); 216 CLR32(dev, REG_CHFORMAT, CHFORMAT_CHB3D5C); 217 CLR32(dev, REG_LEGACY, LEGACY_CHB3D6C); 218 CLR32(dev, REG_CHFORMAT, CHFORMAT_CHB3D); 219 break; 220 } 221 } 222 223 PUT32(dev, port->reg_paddr, port->paddr); 224 PUT16(dev, port->reg_bufsz, (port->bufsz / 4) - 1); 225 PUT16(dev, port->reg_fragsz, (port->fragfr * port->nchan / 2) - 1); 226 227 /* Analog output */ 228 if (port->capture) { 229 /* Analog capture */ 230 SET32(dev, REG_FUNCTRL0, port->fc0_rec_bit); 231 } else { 232 CLR32(dev, REG_FUNCTRL0, port->fc0_rec_bit); 233 } 234 } 235 236 static void 237 cmpci_start_port(cmpci_port_t *port) 238 { 239 cmpci_dev_t *dev = port->dev; 240 241 if (dev->suspended) 242 return; 243 244 SET32(dev, REG_FUNCTRL0, port->fc0_en_bit); 245 SET32(dev, REG_INTCTRL, port->int_en_bit); 246 } 247 248 static void 249 cmpci_stop_port(cmpci_port_t *port) 250 { 251 cmpci_dev_t *dev = port->dev; 252 253 if (dev->suspended) 254 return; 255 256 CLR32(dev, REG_FUNCTRL0, port->fc0_en_bit); 257 CLR32(dev, REG_INTCTRL, port->int_en_bit); 258 } 259 260 static int 261 cmpci_open(void *arg, int flag, uint_t *fragfrp, uint_t *nfp, caddr_t *bufp) 262 { 263 cmpci_port_t *port = arg; 264 cmpci_dev_t *dev = port->dev; 265 266 _NOTE(ARGUNUSED(flag)); 267 268 mutex_enter(&dev->mutex); 269 270 *fragfrp = port->fragfr; 271 *nfp = port->nfrags; 272 *bufp = port->kaddr; 273 274 port->count = 0; 275 port->open = B_TRUE; 276 277 cmpci_reset_port(port); 278 cmpci_start_port(port); 279 280 mutex_exit(&dev->mutex); 281 return (0); 282 } 283 284 static void 285 cmpci_close(void *arg) 286 { 287 cmpci_port_t *port = arg; 288 cmpci_dev_t *dev = port->dev; 289 290 mutex_enter(&dev->mutex); 291 port->open = B_FALSE; 292 cmpci_stop_port(port); 293 mutex_exit(&dev->mutex); 294 } 295 296 static void 297 cmpci_update_port(cmpci_port_t *port) 298 { 299 cmpci_dev_t *dev = port->dev; 300 uint32_t count; 301 uint32_t offset; 302 303 if ((dev->suspended) || (!port->open)) 304 return; 305 306 /* this gives us the offset in dwords */ 307 offset = (port->bufsz / 4) - (GET16(dev, port->reg_bufsz) + 1); 308 309 /* check for wrap - note that the count is given in dwords */ 310 if (offset < port->offset) { 311 count = ((port->bufsz / 4) - port->offset) + offset; 312 } else { 313 count = offset - port->offset; 314 } 315 port->count += count; 316 port->offset = offset; 317 } 318 319 static uint64_t 320 cmpci_count(void *arg) 321 { 322 cmpci_port_t *port = arg; 323 cmpci_dev_t *dev = port->dev; 324 uint64_t count; 325 326 mutex_enter(&dev->mutex); 327 cmpci_update_port(port); 328 329 /* the count is in dwords */ 330 count = port->count; 331 332 mutex_exit(&dev->mutex); 333 334 /* 335 * convert dwords to frames - unfortunately this requires a 336 * divide 337 */ 338 return (count / (port->nchan / 2)); 339 } 340 341 342 static int 343 cmpci_setup_interrupts(cmpci_dev_t *dev) 344 { 345 int actual; 346 uint_t ipri; 347 348 if ((ddi_intr_alloc(dev->dip, &dev->ihandle, DDI_INTR_TYPE_FIXED, 349 0, 1, &actual, DDI_INTR_ALLOC_NORMAL) != DDI_SUCCESS) || 350 (actual != 1)) { 351 audio_dev_warn(dev->adev, "can't alloc intr handle"); 352 return (DDI_FAILURE); 353 } 354 355 if (ddi_intr_get_pri(dev->ihandle, &ipri) != DDI_SUCCESS) { 356 audio_dev_warn(dev->adev, "can't determine intr priority"); 357 (void) ddi_intr_free(dev->ihandle); 358 dev->ihandle = NULL; 359 return (DDI_FAILURE); 360 } 361 362 if (ddi_intr_add_handler(dev->ihandle, cmpci_intr, dev, 363 NULL) != DDI_SUCCESS) { 364 audio_dev_warn(dev->adev, "can't add intr handler"); 365 (void) ddi_intr_free(dev->ihandle); 366 dev->ihandle = NULL; 367 return (DDI_FAILURE); 368 } 369 370 mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, DDI_INTR_PRI(ipri)); 371 372 return (DDI_SUCCESS); 373 } 374 375 376 #define MASK(nbits) ((1 << (nbits)) - 1) 377 #define SCALE(val, nbits) \ 378 ((uint8_t)((((val) * MASK(nbits)) / 100)) << (8 - (nbits))) 379 380 #define LEFT(dev, ctl) min(((dev->controls[ctl].value) >> 8), 100) 381 #define RIGHT(dev, ctl) min(((dev->controls[ctl].value) & 0xff), 100) 382 #define MONO(dev, ctl) min(dev->controls[ctl].value, 100) 383 384 static void 385 cmpci_setmixer(cmpci_dev_t *dev, uint8_t idx, uint8_t val) 386 { 387 PUT8(dev, REG_IDXADDR, idx); 388 PUT8(dev, REG_IDXDATA, val); 389 } 390 391 static uint8_t 392 cmpci_getmixer(cmpci_dev_t *dev, uint8_t idx) 393 { 394 PUT8(dev, REG_IDXADDR, idx); 395 return (GET8(dev, REG_IDXDATA)); 396 } 397 398 399 static void 400 cmpci_configure_mixer(cmpci_dev_t *dev) 401 { 402 uint64_t left, right; 403 uint8_t outmix; 404 uint8_t inmix[2]; 405 uint64_t recsrcs; 406 uint64_t monsrcs; 407 408 if (dev->suspended) 409 return; 410 411 /* reset all mix values */ 412 outmix = inmix[0] = inmix[1] = 0; 413 414 outmix = OUTMIX_MIC | 415 OUTMIX_CD_R | OUTMIX_CD_L | OUTMIX_LINE_R | OUTMIX_LINE_L; 416 417 inmix[0] = INMIX_LINE_L | INMIX_CD_L | INMIX_MIC; 418 inmix[1] = INMIX_LINE_R | INMIX_CD_R | INMIX_MIC; 419 420 recsrcs = dev->controls[CTL_RECSRCS].value; 421 monsrcs = dev->controls[CTL_MONSRCS].value; 422 423 /* program PCM volume */ 424 left = MONO(dev, CTL_VOLUME); 425 if (left) { 426 /* left and right are the same */ 427 cmpci_setmixer(dev, IDX_VOICE_LEFT, SCALE(left, 5)); 428 cmpci_setmixer(dev, IDX_VOICE_RIGHT, SCALE(left, 5)); 429 CLR8(dev, REG_MIX2, MIX2_WSMUTE); 430 } else { 431 cmpci_setmixer(dev, IDX_VOICE_LEFT, 0); 432 cmpci_setmixer(dev, IDX_VOICE_RIGHT, 0); 433 SET8(dev, REG_MIX2, MIX2_WSMUTE); 434 } 435 436 left = LEFT(dev, CTL_LINEOUT); 437 right = RIGHT(dev, CTL_LINEOUT); 438 439 /* lineout/master volume - no separate mute */ 440 cmpci_setmixer(dev, IDX_MASTER_LEFT, SCALE(left, 5)); 441 cmpci_setmixer(dev, IDX_MASTER_RIGHT, SCALE(right, 5)); 442 443 /* speaker volume - mute in extension register, but we don't use */ 444 left = MONO(dev, CTL_SPEAKER); 445 cmpci_setmixer(dev, IDX_SPEAKER, SCALE(left, 2)); 446 447 /* mic gain */ 448 left = MONO(dev, CTL_MIC); 449 if (left) { 450 cmpci_setmixer(dev, IDX_MIC, SCALE(left, 5)); 451 /* set record mic gain */ 452 uint8_t v = GET8(dev, REG_MIX3); 453 v &= ~(0x7 << 1); 454 v |= ((left * 7) / 100) << 1; 455 PUT8(dev, REG_MIX3, v); 456 cmpci_setmixer(dev, 0x3f, SCALE(100, 2)); 457 cmpci_setmixer(dev, 0x40, SCALE(100, 2)); 458 } else { 459 cmpci_setmixer(dev, IDX_MIC, 0); 460 outmix &= ~OUTMIX_MIC; 461 inmix[0] &= ~INMIX_MIC; 462 inmix[1] &= ~INMIX_MIC; 463 } 464 465 /* line in */ 466 left = LEFT(dev, CTL_LINEOUT); 467 right = RIGHT(dev, CTL_LINEOUT); 468 if (left) { 469 cmpci_setmixer(dev, IDX_LINEIN_LEFT, SCALE(left, 5)); 470 } else { 471 cmpci_setmixer(dev, IDX_LINEIN_LEFT, 0); 472 inmix[0] &= ~INMIX_LINE_L; 473 outmix &= ~OUTMIX_LINE_L; 474 } 475 if (right) { 476 cmpci_setmixer(dev, IDX_LINEIN_RIGHT, SCALE(left, 5)); 477 } else { 478 cmpci_setmixer(dev, IDX_LINEIN_RIGHT, 0); 479 inmix[1] &= ~INMIX_LINE_R; 480 outmix &= ~OUTMIX_LINE_R; 481 } 482 483 /* cd */ 484 left = LEFT(dev, CTL_CD); 485 right = RIGHT(dev, CTL_CD); 486 if (left) { 487 cmpci_setmixer(dev, IDX_CDDA_LEFT, SCALE(left, 5)); 488 } else { 489 cmpci_setmixer(dev, IDX_CDDA_LEFT, 0); 490 inmix[0] &= ~INMIX_CD_L; 491 outmix &= ~OUTMIX_CD_L; 492 } 493 if (right) { 494 cmpci_setmixer(dev, IDX_CDDA_RIGHT, SCALE(left, 5)); 495 } else { 496 cmpci_setmixer(dev, IDX_CDDA_RIGHT, 0); 497 inmix[1] &= ~INMIX_CD_R; 498 outmix &= ~OUTMIX_CD_R; 499 } 500 501 /* aux - trickier because it doesn't use regular sbpro mixer */ 502 left = LEFT(dev, CTL_AUX); 503 right = RIGHT(dev, CTL_AUX); 504 PUT8(dev, REG_VAUX, (((left * 15) / 100) << 4) | ((right * 15) / 100)); 505 /* maybe enable recording */ 506 if ((left || right) && (recsrcs & (1 << SRC_LINE))) { 507 SET8(dev, REG_MIX3, MIX3_RAUXREN | MIX3_RAUXLEN); 508 } else { 509 CLR8(dev, REG_MIX3, MIX3_RAUXREN | MIX3_RAUXLEN); 510 } 511 /* maybe enable monitoring */ 512 if ((left || right) && (monsrcs & (1 << SRC_AUX))) { 513 CLR8(dev, REG_MIX3, MIX3_VAUXRM | MIX3_VAUXLM); 514 } else { 515 SET8(dev, REG_MIX3, MIX3_VAUXRM | MIX3_VAUXLM); 516 } 517 518 /* now do the recsrcs */ 519 if ((recsrcs & (1 << SRC_MIC)) == 0) { 520 inmix[0] &= ~INMIX_MIC; 521 inmix[1] &= ~INMIX_MIC; 522 } 523 if ((recsrcs & (1 << SRC_LINE)) == 0) { 524 inmix[0] &= ~INMIX_LINE_L; 525 inmix[1] &= ~INMIX_LINE_R; 526 } 527 if ((recsrcs & (1 << SRC_CD)) == 0) { 528 inmix[0] &= ~INMIX_CD_L; 529 inmix[1] &= ~INMIX_CD_R; 530 } 531 if (recsrcs & (1 << SRC_MIX)) { 532 SET8(dev, REG_MIX2, MIX2_WAVEIN_L | MIX2_WAVEIN_R); 533 } else { 534 CLR8(dev, REG_MIX2, MIX2_WAVEIN_L | MIX2_WAVEIN_R); 535 } 536 cmpci_setmixer(dev, IDX_INMIX_L, inmix[0]); 537 cmpci_setmixer(dev, IDX_INMIX_R, inmix[1]); 538 539 /* now the monsrcs */ 540 if ((monsrcs & (1 << SRC_MIC)) == 0) { 541 outmix &= ~OUTMIX_MIC; 542 } 543 if ((monsrcs & (1 << SRC_LINE)) == 0) { 544 outmix &= ~(OUTMIX_LINE_L | OUTMIX_LINE_R); 545 } 546 if ((monsrcs & (1 << SRC_CD)) == 0) { 547 outmix &= ~(OUTMIX_CD_L | OUTMIX_CD_R); 548 } 549 cmpci_setmixer(dev, IDX_OUTMIX, outmix); 550 551 /* micboost */ 552 if (dev->controls[CTL_MICBOOST].value != 0) { 553 CLR8(dev, REG_MIX3, MIX3_MICGAINZ); 554 cmpci_setmixer(dev, IDX_EXTENSION, 555 cmpci_getmixer(dev, IDX_EXTENSION) & ~0x1); 556 } else { 557 SET8(dev, REG_MIX3, MIX3_MICGAINZ); 558 cmpci_setmixer(dev, IDX_EXTENSION, 559 cmpci_getmixer(dev, IDX_EXTENSION) | 0x1); 560 } 561 } 562 563 static int 564 cmpci_set_ctrl(void *arg, uint64_t val) 565 { 566 cmpci_ctrl_t *cc = arg; 567 cmpci_dev_t *dev = cc->dev; 568 569 /* 570 * We don't bother to check for valid values - a bogus value 571 * will give incorrect volumes, but is otherwise harmless. 572 */ 573 mutex_enter(&dev->mutex); 574 cc->value = val; 575 cmpci_configure_mixer(dev); 576 mutex_exit(&dev->mutex); 577 578 return (0); 579 } 580 581 static int 582 cmpci_get_ctrl(void *arg, uint64_t *val) 583 { 584 cmpci_ctrl_t *cc = arg; 585 cmpci_dev_t *dev = cc->dev; 586 587 mutex_enter(&dev->mutex); 588 *val = cc->value; 589 mutex_exit(&dev->mutex); 590 return (0); 591 } 592 593 #define PLAYCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY) 594 #define RECCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC) 595 #define MONCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR) 596 #define PCMVOL (PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL) 597 #define MAINVOL (PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL) 598 #define RECVOL (RECCTL | AUDIO_CTRL_FLAG_RECVOL) 599 600 static void 601 cmpci_alloc_ctrl(cmpci_dev_t *dev, uint32_t num, uint64_t val) 602 { 603 audio_ctrl_desc_t desc; 604 cmpci_ctrl_t *cc; 605 606 cc = &dev->controls[num]; 607 bzero(&desc, sizeof (desc)); 608 cc->dev = dev; 609 610 switch (num) { 611 case CTL_VOLUME: 612 desc.acd_name = AUDIO_CTRL_ID_VOLUME; 613 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 614 desc.acd_minvalue = 0; 615 desc.acd_maxvalue = 100; 616 desc.acd_flags = PCMVOL; 617 break; 618 619 case CTL_LINEOUT: 620 desc.acd_name = AUDIO_CTRL_ID_LINEOUT; 621 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 622 desc.acd_minvalue = 0; 623 desc.acd_maxvalue = 100; 624 desc.acd_flags = MAINVOL; 625 break; 626 627 case CTL_SPEAKER: 628 desc.acd_name = AUDIO_CTRL_ID_SPEAKER; 629 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 630 desc.acd_minvalue = 0; 631 desc.acd_maxvalue = 100; 632 desc.acd_flags = MAINVOL; 633 break; 634 635 case CTL_MIC: 636 desc.acd_name = AUDIO_CTRL_ID_MIC; 637 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 638 desc.acd_minvalue = 0; 639 desc.acd_maxvalue = 100; 640 desc.acd_flags = RECVOL; 641 break; 642 643 case CTL_LINEIN: 644 desc.acd_name = AUDIO_CTRL_ID_LINEIN; 645 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 646 desc.acd_minvalue = 0; 647 desc.acd_maxvalue = 100; 648 desc.acd_flags = RECVOL; 649 break; 650 651 case CTL_CD: 652 desc.acd_name = AUDIO_CTRL_ID_CD; 653 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 654 desc.acd_minvalue = 0; 655 desc.acd_maxvalue = 100; 656 desc.acd_flags = RECVOL; 657 break; 658 659 case CTL_AUX: 660 desc.acd_name = AUDIO_CTRL_ID_AUX1IN; 661 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 662 desc.acd_minvalue = 0; 663 desc.acd_maxvalue = 100; 664 desc.acd_flags = RECVOL; 665 break; 666 667 case CTL_RECSRCS: 668 desc.acd_name = AUDIO_CTRL_ID_RECSRC; 669 desc.acd_type = AUDIO_CTRL_TYPE_ENUM; 670 desc.acd_enum[SRC_MIC] = AUDIO_PORT_MIC; 671 desc.acd_enum[SRC_LINE] = AUDIO_PORT_LINEIN; 672 desc.acd_enum[SRC_CD] = AUDIO_PORT_CD; 673 desc.acd_enum[SRC_AUX] = AUDIO_PORT_AUX1IN; 674 desc.acd_enum[SRC_MIX] = AUDIO_PORT_STEREOMIX; 675 desc.acd_minvalue = (1 << (SRC_MIX + 1)) - 1; 676 desc.acd_maxvalue = desc.acd_minvalue; 677 desc.acd_flags = RECCTL | AUDIO_CTRL_FLAG_MULTI; 678 break; 679 680 case CTL_MONSRCS: 681 desc.acd_name = AUDIO_CTRL_ID_MONSRC; 682 desc.acd_type = AUDIO_CTRL_TYPE_ENUM; 683 desc.acd_enum[SRC_MIC] = AUDIO_PORT_MIC; 684 desc.acd_enum[SRC_LINE] = AUDIO_PORT_LINEIN; 685 desc.acd_enum[SRC_CD] = AUDIO_PORT_CD; 686 desc.acd_enum[SRC_AUX] = AUDIO_PORT_AUX1IN; 687 desc.acd_minvalue = ((1 << (SRC_AUX + 1)) - 1); 688 desc.acd_maxvalue = desc.acd_minvalue; 689 desc.acd_flags = MONCTL | AUDIO_CTRL_FLAG_MULTI; 690 break; 691 692 case CTL_MICBOOST: 693 desc.acd_name = AUDIO_CTRL_ID_MICBOOST; 694 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN; 695 desc.acd_minvalue = 0; 696 desc.acd_maxvalue = 1; 697 desc.acd_flags = RECCTL; 698 break; 699 } 700 701 cc->value = val; 702 cc->ctrl = audio_dev_add_control(dev->adev, &desc, 703 cmpci_get_ctrl, cmpci_set_ctrl, cc); 704 } 705 706 static void 707 cmpci_add_controls(cmpci_dev_t *dev) 708 { 709 if (dev->softvol) { 710 (void) audio_dev_add_soft_volume(dev->adev); 711 } else { 712 cmpci_alloc_ctrl(dev, CTL_VOLUME, 75); 713 } 714 cmpci_alloc_ctrl(dev, CTL_LINEOUT, 90 | (90 << 8)); 715 cmpci_alloc_ctrl(dev, CTL_SPEAKER, 75); 716 cmpci_alloc_ctrl(dev, CTL_MIC, 32); 717 cmpci_alloc_ctrl(dev, CTL_LINEIN, 64 | (64 << 8)); 718 cmpci_alloc_ctrl(dev, CTL_CD, 75 | (75 << 8)); 719 cmpci_alloc_ctrl(dev, CTL_AUX, 75 | (75 << 8)); 720 cmpci_alloc_ctrl(dev, CTL_RECSRCS, (1 << SRC_MIC)); 721 cmpci_alloc_ctrl(dev, CTL_MONSRCS, 0); 722 cmpci_alloc_ctrl(dev, CTL_MICBOOST, 0); 723 } 724 725 static void 726 cmpci_del_controls(cmpci_dev_t *dev) 727 { 728 for (int i = 0; i < CTL_NUM; i++) { 729 if (dev->controls[i].ctrl) { 730 audio_dev_del_control(dev->controls[i].ctrl); 731 dev->controls[i].ctrl = NULL; 732 } 733 } 734 } 735 736 static void 737 cmpci_reset(cmpci_dev_t *dev) 738 { 739 /* Full reset */ 740 SET32(dev, REG_MISC, MISC_RESET); 741 (void) GET32(dev, REG_MISC); 742 drv_usecwait(100); 743 CLR32(dev, REG_MISC, MISC_RESET); 744 745 /* reset all channels */ 746 PUT32(dev, REG_FUNCTRL0, 0); 747 748 /* disable interrupts and such */ 749 CLR32(dev, REG_FUNCTRL0, FUNCTRL0_CH0_EN | FUNCTRL0_CH1_EN); 750 CLR32(dev, REG_INTCTRL, INTCTRL_CH0_EN | INTCTRL_CH1_EN); 751 752 /* disable uart, joystick in Function Control Reg1 */ 753 CLR32(dev, REG_FUNCTRL1, FUNCTRL1_UART_EN | FUNCTRL1_JYSTK_EN); 754 755 /* 756 * Set DAC and ADC rates to 48 kHz - note that both rates have 757 * all bits set in them, so we can do this with a simple "set". 758 */ 759 SET32(dev, REG_FUNCTRL1, 760 FUNCTRL1_DAC_RATE_48K | FUNCTRL1_ADC_RATE_48K); 761 762 /* Set 16-bit stereo -- also these are just with all bits set. */ 763 SET32(dev, REG_CHFORMAT, CHFORMAT_CH0_16ST | CHFORMAT_CH1_16ST); 764 } 765 766 static int 767 cmpci_format(void *unused) 768 { 769 _NOTE(ARGUNUSED(unused)); 770 return (AUDIO_FORMAT_S16_LE); 771 } 772 773 static int 774 cmpci_channels(void *arg) 775 { 776 cmpci_port_t *port = arg; 777 778 return (port->nchan); 779 } 780 781 static void 782 cmpci_chinfo(void *arg, int chan, unsigned *offset, unsigned *incr) 783 { 784 cmpci_port_t *port = arg; 785 static const int map8ch[] = { 0, 1, 4, 5, 2, 3, 6, 7 }; 786 static const int map4ch[] = { 0, 1, 2, 3 }; 787 788 if (port->nchan <= 4) { 789 *offset = map4ch[chan]; 790 } else { 791 *offset = map8ch[chan]; 792 } 793 *incr = port->nchan; 794 } 795 796 static int 797 cmpci_rate(void *unused) 798 { 799 _NOTE(ARGUNUSED(unused)); 800 return (48000); 801 } 802 803 static void 804 cmpci_sync(void *arg, unsigned nframes) 805 { 806 cmpci_port_t *port = arg; 807 808 _NOTE(ARGUNUSED(nframes)); 809 810 (void) ddi_dma_sync(port->dmah, 0, 0, port->sync_dir); 811 } 812 813 audio_engine_ops_t cmpci_engine_ops = { 814 AUDIO_ENGINE_VERSION, /* version number */ 815 cmpci_open, 816 cmpci_close, 817 NULL, /* start */ 818 NULL, /* stop */ 819 cmpci_count, 820 cmpci_format, 821 cmpci_channels, 822 cmpci_rate, 823 cmpci_sync, 824 NULL, /* qlen */ 825 cmpci_chinfo, 826 NULL, /* playahead */ 827 }; 828 829 static int 830 cmpci_init(cmpci_dev_t *dev) 831 { 832 audio_dev_t *adev = dev->adev; 833 int playch; 834 int intrs; 835 836 dev->pintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip, 837 DDI_PROP_DONTPASS, "play-interrupts", DEFINTS); 838 839 dev->rintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip, 840 DDI_PROP_DONTPASS, "record-interrupts", DEFINTS); 841 842 playch = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip, 843 DDI_PROP_DONTPASS, "channels", dev->maxch); 844 845 if ((playch % 2) || (playch < 2) || (playch > dev->maxch)) { 846 audio_dev_warn(adev, 847 "Invalid channels property (%d), resetting to %d", 848 playch, dev->maxch); 849 playch = dev->maxch; 850 } 851 852 for (int i = 0; i < PORT_MAX; i++) { 853 854 cmpci_port_t *port; 855 unsigned dmaflags; 856 unsigned caps; 857 size_t rlen; 858 ddi_dma_cookie_t c; 859 unsigned ccnt; 860 861 port = &dev->port[i]; 862 port->dev = dev; 863 port->num = i; 864 865 /* 866 * Channel 0 is recording channel, unless we are in 867 * dual DAC mode. The reason for this is simple -- 868 * only channel "B" (which I presume to mean channel 869 * 1) supports multichannel configuration. 870 * 871 * However, if we're going to use SPDIF recording, 872 * then recording *must* occur on channel 1. Yes, the 873 * hardware is "strange". 874 */ 875 876 switch (i) { 877 case 0: 878 caps = ENGINE_INPUT_CAP; 879 dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT; 880 port->callb = audio_engine_produce; 881 port->reg_paddr = REG_CH0_PADDR; 882 port->reg_bufsz = REG_CH0_BUFSZ; 883 port->reg_fragsz = REG_CH0_FRAGSZ; 884 port->fc0_rst_bit = FUNCTRL0_CH0_RST; 885 port->fc0_rec_bit = FUNCTRL0_CH0_REC; 886 port->fc0_en_bit = FUNCTRL0_CH0_EN; 887 port->int_en_bit = INTCTRL_CH0_EN; 888 port->sync_dir = DDI_DMA_SYNC_FORKERNEL; 889 port->capture = B_TRUE; 890 port->fc1_rate_mask = FUNCTRL1_ADC_RATE_48K; 891 port->chformat_mask = CHFORMAT_CH0_16ST; 892 port->nchan = 2; 893 intrs = dev->rintrs; 894 break; 895 896 case 1: 897 caps = ENGINE_OUTPUT_CAP; 898 dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT; 899 port->callb = audio_engine_consume; 900 port->reg_paddr = REG_CH1_PADDR; 901 port->reg_bufsz = REG_CH1_BUFSZ; 902 port->reg_fragsz = REG_CH1_FRAGSZ; 903 port->fc0_rst_bit = FUNCTRL0_CH1_RST; 904 port->fc0_rec_bit = FUNCTRL0_CH1_REC; 905 port->fc0_en_bit = FUNCTRL0_CH1_EN; 906 port->int_en_bit = INTCTRL_CH1_EN; 907 port->sync_dir = DDI_DMA_SYNC_FORDEV; 908 port->capture = B_FALSE; 909 port->fc1_rate_mask = FUNCTRL1_DAC_RATE_48K; 910 port->chformat_mask = CHFORMAT_CH1_16ST; 911 port->nchan = playch; 912 intrs = dev->pintrs; 913 break; 914 } 915 916 /* 917 * Calculate fragfr, nfrags, buf. 918 * 919 * 48 as minimum is chosen to ensure that we will have 920 * at least 4 fragments. 512 is just an arbitrary 921 * limit, and at the smallest frame size will result 922 * in no more than 176 fragments. 923 */ 924 intrs = min(512, max(48, intrs)); 925 926 /* 927 * Two fragments are enough to get ping-pong buffers. 928 * The hardware could support considerably more than 929 * this, but it just wastes memory. 930 */ 931 port->nfrags = 2; 932 933 /* 934 * For efficiency, we'd like to have the fragments 935 * evenly divisble by 64 bytes. Since frames are 936 * already evenly divisble by 4 (16-bit stereo), this 937 * is adequate. For a typical configuration (175 Hz 938 * requested) this will translate to 166 Hz. 939 */ 940 port->fragfr = P2ROUNDUP((48000 / intrs), 16); 941 port->nframes = port->nfrags * port->fragfr; 942 port->bufsz = port->nframes * port->nchan * 2; 943 944 if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_DONTWAIT, 945 NULL, &port->dmah) != DDI_SUCCESS) { 946 audio_dev_warn(adev, "ch%d: dma hdl alloc failed", i); 947 return (DDI_FAILURE); 948 } 949 if (ddi_dma_mem_alloc(port->dmah, port->bufsz, &buf_attr, 950 DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, &port->kaddr, 951 &rlen, &port->acch) != DDI_SUCCESS) { 952 audio_dev_warn(adev, "ch%d: dma mem allcoc failed", i); 953 return (DDI_FAILURE); 954 } 955 bzero(port->kaddr, rlen); 956 957 if (ddi_dma_addr_bind_handle(port->dmah, NULL, port->kaddr, 958 rlen, dmaflags, DDI_DMA_DONTWAIT, NULL, &c, &ccnt) != 959 DDI_DMA_MAPPED) { 960 audio_dev_warn(adev, "ch%d: dma bind failed", i); 961 return (DDI_FAILURE); 962 } 963 port->paddr = c.dmac_address; 964 965 port->engine = audio_engine_alloc(&cmpci_engine_ops, caps); 966 if (port->engine == NULL) { 967 audio_dev_warn(adev, "ch%d: alloc engine failed", i); 968 return (DDI_FAILURE); 969 } 970 audio_engine_set_private(port->engine, port); 971 audio_dev_add_engine(adev, port->engine); 972 } 973 974 cmpci_add_controls(dev); 975 976 dev->ksp = kstat_create(ddi_driver_name(dev->dip), 977 ddi_get_instance(dev->dip), ddi_driver_name(dev->dip), 978 "controller", KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT); 979 if (dev->ksp != NULL) { 980 kstat_install(dev->ksp); 981 } 982 983 cmpci_reset(dev); 984 cmpci_configure_mixer(dev); 985 986 if (audio_dev_register(adev) != DDI_SUCCESS) { 987 audio_dev_warn(adev, "audio_dev_register failed"); 988 return (DDI_FAILURE); 989 } 990 991 return (DDI_SUCCESS); 992 } 993 994 void 995 cmpci_destroy(cmpci_dev_t *dev) 996 { 997 if (dev->ihandle != NULL) { 998 (void) ddi_intr_disable(dev->ihandle); 999 (void) ddi_intr_remove_handler(dev->ihandle); 1000 (void) ddi_intr_free(dev->ihandle); 1001 mutex_destroy(&dev->mutex); 1002 } 1003 1004 if (dev->ksp != NULL) { 1005 kstat_delete(dev->ksp); 1006 } 1007 1008 /* free up ports, including DMA resources for ports */ 1009 for (int i = 0; i < PORT_MAX; i++) { 1010 cmpci_port_t *port = &dev->port[i]; 1011 1012 if (port->paddr != 0) 1013 (void) ddi_dma_unbind_handle(port->dmah); 1014 if (port->acch != NULL) 1015 ddi_dma_mem_free(&port->acch); 1016 if (port->dmah != NULL) 1017 ddi_dma_free_handle(&port->dmah); 1018 1019 if (port->engine != NULL) { 1020 audio_dev_remove_engine(dev->adev, port->engine); 1021 audio_engine_free(port->engine); 1022 } 1023 } 1024 1025 if (dev->acch != NULL) { 1026 ddi_regs_map_free(&dev->acch); 1027 } 1028 1029 cmpci_del_controls(dev); 1030 1031 if (dev->adev != NULL) { 1032 audio_dev_free(dev->adev); 1033 } 1034 1035 kmem_free(dev, sizeof (*dev)); 1036 } 1037 1038 int 1039 cmpci_attach(dev_info_t *dip) 1040 { 1041 uint16_t vendor, device; 1042 cmpci_dev_t *dev; 1043 ddi_acc_handle_t pcih; 1044 audio_dev_t *adev; 1045 uint32_t val; 1046 1047 if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) { 1048 audio_dev_warn(NULL, "pci_config_setup failed"); 1049 return (DDI_FAILURE); 1050 } 1051 1052 vendor = pci_config_get16(pcih, PCI_CONF_VENID); 1053 device = pci_config_get16(pcih, PCI_CONF_DEVID); 1054 1055 if (vendor != CMEDIA_VENDOR_ID || 1056 ((device != CMEDIA_CM8738) && (device != CMEDIA_CM8338A) && 1057 (device != CMEDIA_CM8338B))) { 1058 pci_config_teardown(&pcih); 1059 audio_dev_warn(NULL, "device not recognized"); 1060 return (DDI_FAILURE); 1061 } 1062 1063 /* enable IO and Master accesses */ 1064 pci_config_put16(pcih, PCI_CONF_COMM, 1065 pci_config_get16(pcih, PCI_CONF_COMM) | 1066 PCI_COMM_MAE | PCI_COMM_IO); 1067 1068 pci_config_teardown(&pcih); 1069 1070 dev = kmem_zalloc(sizeof (*dev), KM_SLEEP); 1071 dev->dip = dip; 1072 1073 ddi_set_driver_private(dip, dev); 1074 1075 if ((adev = audio_dev_alloc(dip, 0)) == NULL) { 1076 goto err_exit; 1077 } 1078 dev->adev = adev; 1079 1080 if (ddi_regs_map_setup(dip, 1, &dev->regs, 0, 0, &acc_attr, 1081 &dev->acch) != DDI_SUCCESS) { 1082 audio_dev_warn(adev, "can't map registers"); 1083 goto err_exit; 1084 } 1085 1086 /* setup some initial values */ 1087 dev->maxch = 2; 1088 audio_dev_set_description(adev, "C-Media PCI Audio"); 1089 switch (device) { 1090 case CMEDIA_CM8738: 1091 /* 1092 * Crazy 8738 detection scheme. Reviewing multiple 1093 * different open sources gives multiple different 1094 * answers here. Its unclear how accurate this is. 1095 * The approach taken here is a bit conservative in 1096 * assigning multiple channel support, but for users 1097 * with newer 8768 cards should offer the best 1098 * capability. 1099 */ 1100 val = GET32(dev, REG_INTCTRL) & INTCTRL_MDL_MASK; 1101 if (val == 0) { 1102 1103 if (GET32(dev, REG_CHFORMAT & CHFORMAT_VER_MASK)) { 1104 audio_dev_set_version(adev, "CMI-8738-037"); 1105 dev->maxch = 4; 1106 } else { 1107 audio_dev_set_version(adev, "CMI-8738-033"); 1108 } 1109 } else if ((val & INTCTRL_MDL_068) == INTCTRL_MDL_068) { 1110 audio_dev_set_version(adev, "CMI-8768"); 1111 dev->maxch = 8; 1112 dev->softvol = B_TRUE; /* No hardware PCM volume */ 1113 } else if ((val & INTCTRL_MDL_055) == INTCTRL_MDL_055) { 1114 audio_dev_set_version(adev, "CMI-8738-055"); 1115 dev->maxch = 6; 1116 } else if ((val & INTCTRL_MDL_039) == INTCTRL_MDL_039) { 1117 audio_dev_set_version(adev, "CMI-8738-039"); 1118 dev->maxch = 4; 1119 } else { 1120 audio_dev_set_version(adev, "CMI-8738"); 1121 } 1122 break; 1123 1124 case CMEDIA_CM8338A: 1125 audio_dev_set_version(dev->adev, "CMI-8338"); 1126 break; 1127 1128 case CMEDIA_CM8338B: 1129 audio_dev_set_version(dev->adev, "CMI-8338B"); 1130 break; 1131 } 1132 1133 if (cmpci_setup_interrupts(dev) != DDI_SUCCESS) { 1134 audio_dev_warn(dev->adev, "can't register interrupts"); 1135 goto err_exit; 1136 } 1137 1138 if (cmpci_init(dev) != DDI_SUCCESS) { 1139 audio_dev_warn(dev->adev, "can't init device"); 1140 goto err_exit; 1141 } 1142 1143 (void) ddi_intr_enable(dev->ihandle); 1144 return (DDI_SUCCESS); 1145 1146 err_exit: 1147 cmpci_destroy(dev); 1148 return (DDI_FAILURE); 1149 } 1150 1151 static int 1152 cmpci_resume(cmpci_dev_t *dev) 1153 { 1154 audio_engine_reset(dev->port[0].engine); 1155 audio_engine_reset(dev->port[1].engine); 1156 1157 mutex_enter(&dev->mutex); 1158 dev->suspended = B_FALSE; 1159 1160 cmpci_reset(dev); 1161 /* wait one millisecond, to give reset a chance to get up */ 1162 drv_usecwait(1000); 1163 1164 cmpci_configure_mixer(dev); 1165 1166 for (int i = 0; i < PORT_MAX; i++) { 1167 cmpci_port_t *port = &dev->port[i]; 1168 1169 cmpci_reset_port(port); 1170 if (port->open) { 1171 cmpci_start_port(port); 1172 } 1173 } 1174 mutex_exit(&dev->mutex); 1175 return (DDI_SUCCESS); 1176 } 1177 1178 static int 1179 cmpci_detach(cmpci_dev_t *dev) 1180 { 1181 if (audio_dev_unregister(dev->adev) != DDI_SUCCESS) 1182 return (DDI_FAILURE); 1183 1184 mutex_enter(&dev->mutex); 1185 1186 /* disable interrupts */ 1187 CLR32(dev, REG_INTCTRL, INTCTRL_CH1_EN | INTCTRL_CH0_EN); 1188 1189 /* disable channels */ 1190 PUT32(dev, REG_FUNCTRL0, 0); 1191 1192 mutex_exit(&dev->mutex); 1193 1194 cmpci_destroy(dev); 1195 1196 return (DDI_SUCCESS); 1197 } 1198 1199 static int 1200 cmpci_suspend(cmpci_dev_t *dev) 1201 { 1202 mutex_enter(&dev->mutex); 1203 1204 cmpci_update_port(&dev->port[0]); 1205 cmpci_stop_port(&dev->port[0]); 1206 1207 cmpci_update_port(&dev->port[1]); 1208 cmpci_stop_port(&dev->port[1]); 1209 1210 dev->suspended = B_TRUE; 1211 mutex_exit(&dev->mutex); 1212 1213 return (DDI_SUCCESS); 1214 } 1215 1216 static int 1217 cmpci_quiesce(dev_info_t *dip) 1218 { 1219 cmpci_dev_t *dev; 1220 1221 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1222 return (DDI_FAILURE); 1223 } 1224 1225 /* disable interrupts */ 1226 PUT32(dev, REG_INTCTRL, 0); 1227 1228 /* disable channels */ 1229 PUT32(dev, REG_FUNCTRL0, 0); 1230 1231 return (DDI_SUCCESS); 1232 } 1233 1234 static int 1235 cmpci_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1236 { 1237 cmpci_dev_t *dev; 1238 1239 switch (cmd) { 1240 case DDI_ATTACH: 1241 return (cmpci_attach(dip)); 1242 1243 case DDI_RESUME: 1244 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1245 return (DDI_FAILURE); 1246 } 1247 return (cmpci_resume(dev)); 1248 1249 default: 1250 return (DDI_FAILURE); 1251 } 1252 } 1253 1254 static int 1255 cmpci_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1256 { 1257 cmpci_dev_t *dev; 1258 1259 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1260 return (DDI_FAILURE); 1261 } 1262 1263 switch (cmd) { 1264 case DDI_DETACH: 1265 return (cmpci_detach(dev)); 1266 1267 case DDI_SUSPEND: 1268 return (cmpci_suspend(dev)); 1269 default: 1270 return (DDI_FAILURE); 1271 } 1272 } 1273 1274 static struct dev_ops cmpci_dev_ops = { 1275 DEVO_REV, /* rev */ 1276 0, /* refcnt */ 1277 NULL, /* getinfo */ 1278 nulldev, /* identify */ 1279 nulldev, /* probe */ 1280 cmpci_ddi_attach, /* attach */ 1281 cmpci_ddi_detach, /* detach */ 1282 nodev, /* reset */ 1283 NULL, /* cb_ops */ 1284 NULL, /* bus_ops */ 1285 NULL, /* power */ 1286 cmpci_quiesce, /* quiesce */ 1287 }; 1288 1289 static struct modldrv cmpci_modldrv = { 1290 &mod_driverops, /* drv_modops */ 1291 "C-Media PCI Audio", /* linkinfo */ 1292 &cmpci_dev_ops, /* dev_ops */ 1293 }; 1294 1295 static struct modlinkage modlinkage = { 1296 MODREV_1, 1297 { &cmpci_modldrv, NULL } 1298 }; 1299 1300 int 1301 _init(void) 1302 { 1303 int rv; 1304 1305 audio_init_ops(&cmpci_dev_ops, "audiocmi"); 1306 if ((rv = mod_install(&modlinkage)) != 0) { 1307 audio_fini_ops(&cmpci_dev_ops); 1308 } 1309 return (rv); 1310 } 1311 1312 int 1313 _fini(void) 1314 { 1315 int rv; 1316 if ((rv = mod_remove(&modlinkage)) == 0) { 1317 audio_fini_ops(&cmpci_dev_ops); 1318 } 1319 return (rv); 1320 } 1321 1322 int 1323 _info(struct modinfo *modinfop) 1324 { 1325 return (mod_info(&modlinkage, modinfop)); 1326 } 1327