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 cmpci_alloc_ctrl(dev, CTL_VOLUME, 75); 710 cmpci_alloc_ctrl(dev, CTL_LINEOUT, 90 | (90 << 8)); 711 cmpci_alloc_ctrl(dev, CTL_SPEAKER, 75); 712 cmpci_alloc_ctrl(dev, CTL_MIC, 32); 713 cmpci_alloc_ctrl(dev, CTL_LINEIN, 64 | (64 << 8)); 714 cmpci_alloc_ctrl(dev, CTL_CD, 75 | (75 << 8)); 715 cmpci_alloc_ctrl(dev, CTL_AUX, 75 | (75 << 8)); 716 cmpci_alloc_ctrl(dev, CTL_RECSRCS, (1 << SRC_MIC)); 717 cmpci_alloc_ctrl(dev, CTL_MONSRCS, 0); 718 cmpci_alloc_ctrl(dev, CTL_MICBOOST, 0); 719 } 720 721 static void 722 cmpci_del_controls(cmpci_dev_t *dev) 723 { 724 for (int i = 0; i < CTL_NUM; i++) { 725 if (dev->controls[i].ctrl) { 726 audio_dev_del_control(dev->controls[i].ctrl); 727 dev->controls[i].ctrl = NULL; 728 } 729 } 730 } 731 732 static void 733 cmpci_reset(cmpci_dev_t *dev) 734 { 735 /* Full reset */ 736 SET32(dev, REG_MISC, MISC_RESET); 737 (void) GET32(dev, REG_MISC); 738 drv_usecwait(100); 739 CLR32(dev, REG_MISC, MISC_RESET); 740 741 /* reset all channels */ 742 PUT32(dev, REG_FUNCTRL0, 0); 743 744 /* disable interrupts and such */ 745 CLR32(dev, REG_FUNCTRL0, FUNCTRL0_CH0_EN | FUNCTRL0_CH1_EN); 746 CLR32(dev, REG_INTCTRL, INTCTRL_CH0_EN | INTCTRL_CH1_EN); 747 748 /* disable uart, joystick in Function Control Reg1 */ 749 CLR32(dev, REG_FUNCTRL1, FUNCTRL1_UART_EN | FUNCTRL1_JYSTK_EN); 750 751 /* 752 * Set DAC and ADC rates to 48 kHz - note that both rates have 753 * all bits set in them, so we can do this with a simple "set". 754 */ 755 SET32(dev, REG_FUNCTRL1, 756 FUNCTRL1_DAC_RATE_48K | FUNCTRL1_ADC_RATE_48K); 757 758 /* Set 16-bit stereo -- also these are just with all bits set. */ 759 SET32(dev, REG_CHFORMAT, CHFORMAT_CH0_16ST | CHFORMAT_CH1_16ST); 760 } 761 762 static int 763 cmpci_format(void *unused) 764 { 765 _NOTE(ARGUNUSED(unused)); 766 return (AUDIO_FORMAT_S16_LE); 767 } 768 769 static int 770 cmpci_channels(void *arg) 771 { 772 cmpci_port_t *port = arg; 773 774 return (port->nchan); 775 } 776 777 static void 778 cmpci_chinfo(void *arg, int chan, unsigned *offset, unsigned *incr) 779 { 780 cmpci_port_t *port = arg; 781 static const int map8ch[] = { 0, 1, 4, 5, 2, 3, 6, 7 }; 782 static const int map4ch[] = { 0, 1, 2, 3 }; 783 784 if (port->nchan <= 4) { 785 *offset = map4ch[chan]; 786 } else { 787 *offset = map8ch[chan]; 788 } 789 *incr = port->nchan; 790 } 791 792 static int 793 cmpci_rate(void *unused) 794 { 795 _NOTE(ARGUNUSED(unused)); 796 return (48000); 797 } 798 799 static void 800 cmpci_sync(void *arg, unsigned nframes) 801 { 802 cmpci_port_t *port = arg; 803 804 _NOTE(ARGUNUSED(nframes)); 805 806 (void) ddi_dma_sync(port->dmah, 0, 0, port->sync_dir); 807 } 808 809 static size_t 810 cmpci_qlen(void *unused) 811 { 812 _NOTE(ARGUNUSED(unused)); 813 814 return (0); 815 } 816 817 audio_engine_ops_t cmpci_engine_ops = { 818 AUDIO_ENGINE_VERSION, /* version number */ 819 cmpci_open, 820 cmpci_close, 821 NULL, /* start */ 822 NULL, /* stop */ 823 cmpci_count, 824 cmpci_format, 825 cmpci_channels, 826 cmpci_rate, 827 cmpci_sync, 828 cmpci_qlen, 829 cmpci_chinfo, 830 }; 831 832 static int 833 cmpci_init(cmpci_dev_t *dev) 834 { 835 audio_dev_t *adev = dev->adev; 836 int playch; 837 int intrs; 838 839 dev->pintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip, 840 DDI_PROP_DONTPASS, "play-interrupts", DEFINTS); 841 842 dev->rintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip, 843 DDI_PROP_DONTPASS, "record-interrupts", DEFINTS); 844 845 playch = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip, 846 DDI_PROP_DONTPASS, "channels", dev->maxch); 847 848 if ((playch % 2) || (playch < 2) || (playch > dev->maxch)) { 849 audio_dev_warn(adev, 850 "Invalid channels property (%d), resetting to %d", 851 playch, dev->maxch); 852 playch = dev->maxch; 853 } 854 855 for (int i = 0; i < PORT_MAX; i++) { 856 857 cmpci_port_t *port; 858 unsigned dmaflags; 859 unsigned caps; 860 size_t rlen; 861 ddi_dma_cookie_t c; 862 unsigned ccnt; 863 864 port = &dev->port[i]; 865 port->dev = dev; 866 port->num = i; 867 868 /* 869 * Channel 0 is recording channel, unless we are in 870 * dual DAC mode. The reason for this is simple -- 871 * only channel "B" (which I presume to mean channel 872 * 1) supports multichannel configuration. 873 * 874 * However, if we're going to use SPDIF recording, 875 * then recording *must* occur on channel 1. Yes, the 876 * hardware is "strange". 877 */ 878 879 switch (i) { 880 case 0: 881 caps = ENGINE_INPUT_CAP; 882 dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT; 883 port->callb = audio_engine_produce; 884 port->reg_paddr = REG_CH0_PADDR; 885 port->reg_bufsz = REG_CH0_BUFSZ; 886 port->reg_fragsz = REG_CH0_FRAGSZ; 887 port->fc0_rst_bit = FUNCTRL0_CH0_RST; 888 port->fc0_rec_bit = FUNCTRL0_CH0_REC; 889 port->fc0_en_bit = FUNCTRL0_CH0_EN; 890 port->int_en_bit = INTCTRL_CH0_EN; 891 port->sync_dir = DDI_DMA_SYNC_FORKERNEL; 892 port->capture = B_TRUE; 893 port->fc1_rate_mask = FUNCTRL1_ADC_RATE_48K; 894 port->chformat_mask = CHFORMAT_CH0_16ST; 895 port->nchan = 2; 896 intrs = dev->rintrs; 897 break; 898 899 case 1: 900 caps = ENGINE_OUTPUT_CAP; 901 dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT; 902 port->callb = audio_engine_consume; 903 port->reg_paddr = REG_CH1_PADDR; 904 port->reg_bufsz = REG_CH1_BUFSZ; 905 port->reg_fragsz = REG_CH1_FRAGSZ; 906 port->fc0_rst_bit = FUNCTRL0_CH1_RST; 907 port->fc0_rec_bit = FUNCTRL0_CH1_REC; 908 port->fc0_en_bit = FUNCTRL0_CH1_EN; 909 port->int_en_bit = INTCTRL_CH1_EN; 910 port->sync_dir = DDI_DMA_SYNC_FORDEV; 911 port->capture = B_FALSE; 912 port->fc1_rate_mask = FUNCTRL1_DAC_RATE_48K; 913 port->chformat_mask = CHFORMAT_CH1_16ST; 914 port->nchan = playch; 915 intrs = dev->pintrs; 916 break; 917 } 918 919 /* 920 * Calculate fragfr, nfrags, buf. 921 * 922 * 48 as minimum is chosen to ensure that we will have 923 * at least 4 fragments. 512 is just an arbitrary 924 * limit, and at the smallest frame size will result 925 * in no more than 176 fragments. 926 */ 927 intrs = min(512, max(48, intrs)); 928 929 /* 930 * Two fragments are enough to get ping-pong buffers. 931 * The hardware could support considerably more than 932 * this, but it just wastes memory. 933 */ 934 port->nfrags = 2; 935 936 /* 937 * For efficiency, we'd like to have the fragments 938 * evenly divisble by 64 bytes. Since frames are 939 * already evenly divisble by 4 (16-bit stereo), this 940 * is adequate. For a typical configuration (175 Hz 941 * requested) this will translate to 166 Hz. 942 */ 943 port->fragfr = P2ROUNDUP((48000 / intrs), 16); 944 port->nframes = port->nfrags * port->fragfr; 945 port->bufsz = port->nframes * port->nchan * 2; 946 947 if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_DONTWAIT, 948 NULL, &port->dmah) != DDI_SUCCESS) { 949 audio_dev_warn(adev, "ch%d: dma hdl alloc failed", i); 950 return (DDI_FAILURE); 951 } 952 if (ddi_dma_mem_alloc(port->dmah, port->bufsz, &buf_attr, 953 DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, &port->kaddr, 954 &rlen, &port->acch) != DDI_SUCCESS) { 955 audio_dev_warn(adev, "ch%d: dma mem allcoc failed", i); 956 return (DDI_FAILURE); 957 } 958 bzero(port->kaddr, rlen); 959 960 if (ddi_dma_addr_bind_handle(port->dmah, NULL, port->kaddr, 961 rlen, dmaflags, DDI_DMA_DONTWAIT, NULL, &c, &ccnt) != 962 DDI_DMA_MAPPED) { 963 audio_dev_warn(adev, "ch%d: dma bind failed", i); 964 return (DDI_FAILURE); 965 } 966 port->paddr = c.dmac_address; 967 968 port->engine = audio_engine_alloc(&cmpci_engine_ops, caps); 969 if (port->engine == NULL) { 970 audio_dev_warn(adev, "ch%d: alloc engine failed", i); 971 return (DDI_FAILURE); 972 } 973 audio_engine_set_private(port->engine, port); 974 audio_dev_add_engine(adev, port->engine); 975 } 976 977 cmpci_add_controls(dev); 978 979 dev->ksp = kstat_create(ddi_driver_name(dev->dip), 980 ddi_get_instance(dev->dip), ddi_driver_name(dev->dip), 981 "controller", KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT); 982 if (dev->ksp != NULL) { 983 kstat_install(dev->ksp); 984 } 985 986 cmpci_reset(dev); 987 cmpci_configure_mixer(dev); 988 989 if (audio_dev_register(adev) != DDI_SUCCESS) { 990 audio_dev_warn(adev, "audio_dev_register failed"); 991 return (DDI_FAILURE); 992 } 993 994 return (DDI_SUCCESS); 995 } 996 997 void 998 cmpci_destroy(cmpci_dev_t *dev) 999 { 1000 if (dev->ihandle != NULL) { 1001 (void) ddi_intr_disable(dev->ihandle); 1002 (void) ddi_intr_remove_handler(dev->ihandle); 1003 (void) ddi_intr_free(dev->ihandle); 1004 mutex_destroy(&dev->mutex); 1005 } 1006 1007 if (dev->ksp != NULL) { 1008 kstat_delete(dev->ksp); 1009 } 1010 1011 /* free up ports, including DMA resources for ports */ 1012 for (int i = 0; i < PORT_MAX; i++) { 1013 cmpci_port_t *port = &dev->port[i]; 1014 1015 if (port->paddr != 0) 1016 (void) ddi_dma_unbind_handle(port->dmah); 1017 if (port->acch != NULL) 1018 ddi_dma_mem_free(&port->acch); 1019 if (port->dmah != NULL) 1020 ddi_dma_free_handle(&port->dmah); 1021 1022 if (port->engine != NULL) { 1023 audio_dev_remove_engine(dev->adev, port->engine); 1024 audio_engine_free(port->engine); 1025 } 1026 } 1027 1028 if (dev->acch != NULL) { 1029 ddi_regs_map_free(&dev->acch); 1030 } 1031 1032 cmpci_del_controls(dev); 1033 1034 if (dev->adev != NULL) { 1035 audio_dev_free(dev->adev); 1036 } 1037 1038 kmem_free(dev, sizeof (*dev)); 1039 } 1040 1041 int 1042 cmpci_attach(dev_info_t *dip) 1043 { 1044 uint16_t vendor, device; 1045 cmpci_dev_t *dev; 1046 ddi_acc_handle_t pcih; 1047 audio_dev_t *adev; 1048 uint32_t val; 1049 1050 if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) { 1051 audio_dev_warn(NULL, "pci_config_setup failed"); 1052 return (DDI_FAILURE); 1053 } 1054 1055 vendor = pci_config_get16(pcih, PCI_CONF_VENID); 1056 device = pci_config_get16(pcih, PCI_CONF_DEVID); 1057 1058 if (vendor != CMEDIA_VENDOR_ID || 1059 ((device != CMEDIA_CM8738) && (device != CMEDIA_CM8338A) && 1060 (device != CMEDIA_CM8338B))) { 1061 pci_config_teardown(&pcih); 1062 audio_dev_warn(NULL, "device not recognized"); 1063 return (DDI_FAILURE); 1064 } 1065 1066 /* enable IO and Master accesses */ 1067 pci_config_put16(pcih, PCI_CONF_COMM, 1068 pci_config_get16(pcih, PCI_CONF_COMM) | 1069 PCI_COMM_MAE | PCI_COMM_IO); 1070 1071 pci_config_teardown(&pcih); 1072 1073 dev = kmem_zalloc(sizeof (*dev), KM_SLEEP); 1074 dev->dip = dip; 1075 1076 ddi_set_driver_private(dip, dev); 1077 1078 if ((adev = audio_dev_alloc(dip, 0)) == NULL) { 1079 goto err_exit; 1080 } 1081 dev->adev = adev; 1082 1083 if (ddi_regs_map_setup(dip, 1, &dev->regs, 0, 0, &acc_attr, 1084 &dev->acch) != DDI_SUCCESS) { 1085 audio_dev_warn(adev, "can't map registers"); 1086 goto err_exit; 1087 } 1088 1089 /* setup some initial values */ 1090 dev->maxch = 2; 1091 audio_dev_set_description(adev, "C-Media PCI Audio"); 1092 switch (device) { 1093 case CMEDIA_CM8738: 1094 /* 1095 * Crazy 8738 detection scheme. Reviewing multiple 1096 * different open sources gives multiple different 1097 * answers here. Its unclear how accurate this is. 1098 * The approach taken here is a bit conservative in 1099 * assigning multiple channel support, but for users 1100 * with newer 8768 cards should offer the best 1101 * capability. 1102 */ 1103 val = GET32(dev, REG_INTCTRL) & INTCTRL_MDL_MASK; 1104 if (val == 0) { 1105 1106 if (GET32(dev, REG_CHFORMAT & CHFORMAT_VER_MASK)) { 1107 audio_dev_set_version(adev, "CMI-8738-037"); 1108 dev->maxch = 4; 1109 } else { 1110 audio_dev_set_version(adev, "CMI-8738-033"); 1111 } 1112 } else if ((val & INTCTRL_MDL_068) == INTCTRL_MDL_068) { 1113 audio_dev_set_version(adev, "CMI-8768"); 1114 dev->maxch = 8; 1115 } else if ((val & INTCTRL_MDL_055) == INTCTRL_MDL_055) { 1116 audio_dev_set_version(adev, "CMI-8738-055"); 1117 dev->maxch = 6; 1118 } else if ((val & INTCTRL_MDL_039) == INTCTRL_MDL_039) { 1119 audio_dev_set_version(adev, "CMI-8738-039"); 1120 dev->maxch = 4; 1121 } else { 1122 audio_dev_set_version(adev, "CMI-8738"); 1123 } 1124 break; 1125 1126 case CMEDIA_CM8338A: 1127 audio_dev_set_version(dev->adev, "CMI-8338"); 1128 break; 1129 1130 case CMEDIA_CM8338B: 1131 audio_dev_set_version(dev->adev, "CMI-8338B"); 1132 break; 1133 } 1134 1135 if (cmpci_setup_interrupts(dev) != DDI_SUCCESS) { 1136 audio_dev_warn(dev->adev, "can't register interrupts"); 1137 goto err_exit; 1138 } 1139 1140 if (cmpci_init(dev) != DDI_SUCCESS) { 1141 audio_dev_warn(dev->adev, "can't init device"); 1142 goto err_exit; 1143 } 1144 1145 (void) ddi_intr_enable(dev->ihandle); 1146 return (DDI_SUCCESS); 1147 1148 err_exit: 1149 cmpci_destroy(dev); 1150 return (DDI_FAILURE); 1151 } 1152 1153 static int 1154 cmpci_resume(cmpci_dev_t *dev) 1155 { 1156 audio_engine_reset(dev->port[0].engine); 1157 audio_engine_reset(dev->port[1].engine); 1158 1159 mutex_enter(&dev->mutex); 1160 dev->suspended = B_FALSE; 1161 1162 cmpci_reset(dev); 1163 /* wait one millisecond, to give reset a chance to get up */ 1164 drv_usecwait(1000); 1165 1166 cmpci_configure_mixer(dev); 1167 1168 for (int i = 0; i < PORT_MAX; i++) { 1169 cmpci_port_t *port = &dev->port[i]; 1170 1171 cmpci_reset_port(port); 1172 if (port->open) { 1173 cmpci_start_port(port); 1174 } 1175 } 1176 mutex_exit(&dev->mutex); 1177 return (DDI_SUCCESS); 1178 } 1179 1180 static int 1181 cmpci_detach(cmpci_dev_t *dev) 1182 { 1183 if (audio_dev_unregister(dev->adev) != DDI_SUCCESS) 1184 return (DDI_FAILURE); 1185 1186 mutex_enter(&dev->mutex); 1187 1188 /* disable interrupts */ 1189 CLR32(dev, REG_INTCTRL, INTCTRL_CH1_EN | INTCTRL_CH0_EN); 1190 1191 /* disable channels */ 1192 PUT32(dev, REG_FUNCTRL0, 0); 1193 1194 mutex_exit(&dev->mutex); 1195 1196 cmpci_destroy(dev); 1197 1198 return (DDI_SUCCESS); 1199 } 1200 1201 static int 1202 cmpci_suspend(cmpci_dev_t *dev) 1203 { 1204 mutex_enter(&dev->mutex); 1205 1206 cmpci_update_port(&dev->port[0]); 1207 cmpci_stop_port(&dev->port[0]); 1208 1209 cmpci_update_port(&dev->port[1]); 1210 cmpci_stop_port(&dev->port[1]); 1211 1212 dev->suspended = B_TRUE; 1213 mutex_exit(&dev->mutex); 1214 1215 return (DDI_SUCCESS); 1216 } 1217 1218 static int 1219 cmpci_quiesce(dev_info_t *dip) 1220 { 1221 cmpci_dev_t *dev; 1222 1223 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1224 return (DDI_FAILURE); 1225 } 1226 1227 /* disable interrupts */ 1228 PUT32(dev, REG_INTCTRL, 0); 1229 1230 /* disable channels */ 1231 PUT32(dev, REG_FUNCTRL0, 0); 1232 1233 return (DDI_SUCCESS); 1234 } 1235 1236 static int 1237 cmpci_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1238 { 1239 cmpci_dev_t *dev; 1240 1241 switch (cmd) { 1242 case DDI_ATTACH: 1243 return (cmpci_attach(dip)); 1244 1245 case DDI_RESUME: 1246 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1247 return (DDI_FAILURE); 1248 } 1249 return (cmpci_resume(dev)); 1250 1251 default: 1252 return (DDI_FAILURE); 1253 } 1254 } 1255 1256 static int 1257 cmpci_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1258 { 1259 cmpci_dev_t *dev; 1260 1261 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1262 return (DDI_FAILURE); 1263 } 1264 1265 switch (cmd) { 1266 case DDI_DETACH: 1267 return (cmpci_detach(dev)); 1268 1269 case DDI_SUSPEND: 1270 return (cmpci_suspend(dev)); 1271 default: 1272 return (DDI_FAILURE); 1273 } 1274 } 1275 1276 static struct dev_ops cmpci_dev_ops = { 1277 DEVO_REV, /* rev */ 1278 0, /* refcnt */ 1279 NULL, /* getinfo */ 1280 nulldev, /* identify */ 1281 nulldev, /* probe */ 1282 cmpci_ddi_attach, /* attach */ 1283 cmpci_ddi_detach, /* detach */ 1284 nodev, /* reset */ 1285 NULL, /* cb_ops */ 1286 NULL, /* bus_ops */ 1287 NULL, /* power */ 1288 cmpci_quiesce, /* quiesce */ 1289 }; 1290 1291 static struct modldrv cmpci_modldrv = { 1292 &mod_driverops, /* drv_modops */ 1293 "C-Media PCI Audio", /* linkinfo */ 1294 &cmpci_dev_ops, /* dev_ops */ 1295 }; 1296 1297 static struct modlinkage modlinkage = { 1298 MODREV_1, 1299 { &cmpci_modldrv, NULL } 1300 }; 1301 1302 int 1303 _init(void) 1304 { 1305 int rv; 1306 1307 audio_init_ops(&cmpci_dev_ops, "audiocmi"); 1308 if ((rv = mod_install(&modlinkage)) != 0) { 1309 audio_fini_ops(&cmpci_dev_ops); 1310 } 1311 return (rv); 1312 } 1313 1314 int 1315 _fini(void) 1316 { 1317 int rv; 1318 if ((rv = mod_remove(&modlinkage)) == 0) { 1319 audio_fini_ops(&cmpci_dev_ops); 1320 } 1321 return (rv); 1322 } 1323 1324 int 1325 _info(struct modinfo *modinfop) 1326 { 1327 return (mod_info(&modlinkage, modinfop)); 1328 } 1329