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 2010 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * Purpose: Creative/Ensoniq AudioPCI driver (ES1370) 27 * 28 * This driver is used with the original Ensoniq AudioPCI. 29 */ 30 31 /* 32 * This file is part of Open Sound System 33 * 34 * Copyright (C) 4Front Technologies 1996-2008. 35 * 36 * This software is released under CDDL 1.0 source license. 37 * See the COPYING file included in the main directory of this source 38 * distribution for the license terms and conditions. 39 */ 40 41 #include <sys/audio/audio_driver.h> 42 #include <sys/note.h> 43 #include <sys/pci.h> 44 #include "audiopci.h" 45 46 /* 47 * The original OSS driver used a single duplex engine and a separate 48 * playback only engine. Instead, we expose three engines, one for input 49 * and two for output. 50 */ 51 52 #define ENSONIQ_VENDOR_ID 0x1274 53 #define CREATIVE_VENDOR_ID 0x1102 54 #define ENSONIQ_ES1370 0x5000 55 56 #define DRVNAME "audiopci" 57 58 #define INPUT_MIC 0 59 #define INPUT_LINEIN 1 60 #define INPUT_CD 2 61 #define INPUT_VIDEO 3 62 #define INPUT_PHONE 4 63 #define INSRCS 0x1f /* bits 0-4 */ 64 65 static const char *audiopci_insrcs[] = { 66 AUDIO_PORT_MIC, 67 AUDIO_PORT_LINEIN, 68 AUDIO_PORT_CD, 69 AUDIO_PORT_VIDEO, 70 AUDIO_PORT_PHONE, 71 NULL 72 }; 73 74 typedef struct audiopci_port 75 { 76 /* Audio parameters */ 77 int speed; 78 int fmt; 79 80 int num; 81 #define PORT_DAC 0 82 #define PORT_SYN 1 83 #define PORT_ADC 2 84 #define PORT_MAX PORT_ADC 85 86 caddr_t kaddr; 87 uint32_t paddr; 88 ddi_acc_handle_t acch; 89 ddi_dma_handle_t dmah; 90 unsigned nframes; 91 unsigned frameno; 92 uint64_t count; 93 94 struct audiopci_dev *dev; 95 audio_engine_t *engine; 96 } audiopci_port_t; 97 98 typedef enum { 99 CTL_VOLUME = 0, 100 CTL_FRONT, 101 CTL_MONO, 102 CTL_MIC, 103 CTL_LINE, 104 CTL_CD, 105 CTL_VID, 106 CTL_PHONE, 107 CTL_MICBOOST, 108 CTL_RECSRC, 109 CTL_MONSRC, 110 CTL_NUM /* must be last */ 111 } audiopci_ctrl_num_t; 112 113 typedef struct audiopci_ctrl 114 { 115 struct audiopci_dev *dev; 116 audio_ctrl_t *ctrl; 117 audiopci_ctrl_num_t num; 118 uint64_t val; 119 } audiopci_ctrl_t; 120 121 122 typedef struct audiopci_dev 123 { 124 audio_dev_t *adev; 125 kmutex_t mutex; 126 uint16_t devid; 127 dev_info_t *dip; 128 129 uint8_t ak_regs[0x20]; 130 int micbias; 131 132 /* 133 * Controls 134 */ 135 audiopci_ctrl_t controls[CTL_NUM]; 136 #if 0 137 audiopci_ctrl_t *micbias; 138 #endif 139 140 audiopci_port_t port[PORT_MAX + 1]; 141 142 143 caddr_t regs; 144 ddi_acc_handle_t acch; 145 } audiopci_dev_t; 146 147 static ddi_device_acc_attr_t acc_attr = { 148 DDI_DEVICE_ATTR_V0, 149 DDI_STRUCTURE_LE_ACC, 150 DDI_STRICTORDER_ACC 151 }; 152 153 static ddi_device_acc_attr_t buf_attr = { 154 DDI_DEVICE_ATTR_V0, 155 DDI_NEVERSWAP_ACC, 156 DDI_STRICTORDER_ACC 157 }; 158 159 /* 160 * The hardware appears to be able to address up to 16-bits worth of longwords, 161 * giving a total address space of 256K. But we need substantially less. 162 */ 163 #define AUDIOPCI_BUF_LEN (16384) 164 165 static ddi_dma_attr_t dma_attr = { 166 DMA_ATTR_VERSION, /* dma_attr_version */ 167 0x0, /* dma_attr_addr_lo */ 168 0xffffffffU, /* dma_attr_addr_hi */ 169 0x3ffff, /* dma_attr_count_max */ 170 0x8, /* dma_attr_align */ 171 0x7f, /* dma_attr_burstsizes */ 172 0x1, /* dma_attr_minxfer */ 173 0x3ffff, /* dma_attr_maxxfer */ 174 0x3ffff, /* dma_attr_seg */ 175 0x1, /* dma_attr_sgllen */ 176 0x1, /* dma_attr_granular */ 177 0 /* dma_attr_flags */ 178 }; 179 180 #define GET8(dev, offset) \ 181 ddi_get8(dev->acch, (uint8_t *)(dev->regs + (offset))) 182 #define GET16(dev, offset) \ 183 ddi_get16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset))) 184 #define GET32(dev, offset) \ 185 ddi_get32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset))) 186 #define PUT8(dev, offset, v) \ 187 ddi_put8(dev->acch, (uint8_t *)(dev->regs + (offset)), v) 188 #define PUT16(dev, offset, v) \ 189 ddi_put16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)), v) 190 #define PUT32(dev, offset, v) \ 191 ddi_put32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)), v) 192 193 #define CLR8(dev, offset, v) PUT8(dev, offset, GET8(dev, offset) & ~(v)) 194 #define SET8(dev, offset, v) PUT8(dev, offset, GET8(dev, offset) | (v)) 195 #define CLR16(dev, offset, v) PUT16(dev, offset, GET16(dev, offset) & ~(v)) 196 #define SET16(dev, offset, v) PUT16(dev, offset, GET16(dev, offset) | (v)) 197 198 static void audiopci_init_hw(audiopci_dev_t *); 199 static void audiopci_init_port(audiopci_port_t *); 200 static uint16_t audiopci_dac_rate(int); 201 static int audiopci_add_controls(audiopci_dev_t *); 202 static void audiopci_del_controls(audiopci_dev_t *); 203 static void audiopci_ak_write(audiopci_dev_t *, uint16_t, uint8_t); 204 205 static int 206 audiopci_ak_wait(audiopci_dev_t *dev, uint8_t wstat) 207 { 208 for (int i = 4000; i; i--) { 209 if (!(GET8(dev, CONC_bCODECSTAT_OFF) & wstat)) 210 return (DDI_SUCCESS); 211 drv_usecwait(10); 212 } 213 return (DDI_FAILURE); 214 } 215 216 static void 217 audiopci_ak_idle(audiopci_dev_t *dev) 218 { 219 for (int i = 0; i < 5; i++) { 220 if (audiopci_ak_wait(dev, CONC_CSTAT_CSTAT) == DDI_SUCCESS) 221 return; 222 } 223 audio_dev_warn(dev->adev, "timed out waiting for codec to idle"); 224 } 225 226 static void 227 audiopci_ak_write(audiopci_dev_t *dev, uint16_t addr, uint8_t data) 228 { 229 uint8_t wstat; 230 231 /* shadow the value */ 232 dev->ak_regs[addr] = data; 233 234 wstat = addr == CODEC_RESET_PWRD ? CONC_CSTAT_CWRIP : CONC_CSTAT_CSTAT; 235 236 /* wait for codec to be available */ 237 if (audiopci_ak_wait(dev, wstat) != DDI_SUCCESS) { 238 audio_dev_warn(dev->adev, "timeout waiting for codec"); 239 } 240 241 PUT16(dev, CONC_wCODECCTL_OFF, (addr << 8) | data); 242 } 243 244 static void 245 audiopci_writemem(audiopci_dev_t *dev, uint32_t page, uint32_t offs, 246 uint32_t data) 247 { 248 /* Select memory page */ 249 PUT32(dev, CONC_bMEMPAGE_OFF, page); 250 PUT32(dev, offs, data); 251 } 252 253 static uint32_t 254 audiopci_readmem(audiopci_dev_t *dev, uint32_t page, uint32_t offs) 255 { 256 PUT32(dev, CONC_bMEMPAGE_OFF, page); /* Select memory page */ 257 return (GET32(dev, offs)); 258 } 259 260 /* 261 * Audio routines 262 */ 263 264 static int 265 audiopci_format(void *arg) 266 { 267 _NOTE(ARGUNUSED(arg)); 268 return (AUDIO_FORMAT_S16_LE); 269 } 270 271 static int 272 audiopci_channels(void *arg) 273 { 274 _NOTE(ARGUNUSED(arg)); 275 return (2); 276 } 277 278 static int 279 audiopci_rate(void *arg) 280 { 281 audiopci_port_t *port = arg; 282 283 return (port->speed); 284 } 285 286 static void 287 audiopci_init_port(audiopci_port_t *port) 288 { 289 audiopci_dev_t *dev = port->dev; 290 unsigned tmp; 291 292 switch (port->num) { 293 case PORT_DAC: 294 295 /* Set physical address of the DMA buffer */ 296 audiopci_writemem(dev, CONC_DACCTL_PAGE, CONC_dDACPADDR_OFF, 297 port->paddr); 298 299 /* Set DAC rate */ 300 PUT16(dev, CONC_wDACRATE_OFF, audiopci_dac_rate(48000)); 301 302 /* Set format */ 303 tmp = GET8(dev, CONC_bSERFMT_OFF); 304 tmp |= CONC_PCM_DAC_16BIT; 305 tmp |= CONC_PCM_DAC_STEREO; 306 307 PUT8(dev, CONC_bSKIPC_OFF, 0x10); 308 PUT8(dev, CONC_bSERFMT_OFF, tmp); 309 310 /* Set the frame count */ 311 audiopci_writemem(dev, CONC_DACCTL_PAGE, CONC_wDACFC_OFF, 312 port->nframes - 1); 313 314 /* Set # of frames between interrupts */ 315 PUT16(dev, CONC_wDACIC_OFF, port->nframes - 1); 316 317 break; 318 319 case PORT_SYN: 320 321 /* Set physical address of the DMA buffer */ 322 audiopci_writemem(dev, CONC_SYNCTL_PAGE, CONC_dSYNPADDR_OFF, 323 port->paddr); 324 325 /* Set rate - we force to 44.1 kHz */ 326 SET8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_SYN_44KHZ); 327 328 /* Set format */ 329 tmp = GET8(dev, CONC_bSERFMT_OFF); 330 tmp |= CONC_PCM_SYN_16BIT; 331 tmp |= CONC_PCM_SYN_STEREO; 332 333 PUT8(dev, CONC_bSERFMT_OFF, tmp); 334 335 /* Set the frame count */ 336 audiopci_writemem(dev, CONC_SYNCTL_PAGE, CONC_wSYNFC_OFF, 337 port->nframes - 1); 338 339 /* Set # of frames between interrupts */ 340 PUT16(dev, CONC_wSYNIC_OFF, port->nframes - 1); 341 342 break; 343 344 case PORT_ADC: 345 /* Set physical address of the DMA buffer */ 346 audiopci_writemem(dev, CONC_ADCCTL_PAGE, CONC_dADCPADDR_OFF, 347 port->paddr); 348 349 /* Set ADC rate */ 350 PUT16(dev, CONC_wDACRATE_OFF, audiopci_dac_rate(48000)); 351 352 /* Set format - for input we only support 16 bit input */ 353 tmp = GET8(dev, CONC_bSERFMT_OFF); 354 tmp |= CONC_PCM_ADC_16BIT; 355 tmp |= CONC_PCM_ADC_STEREO; 356 357 PUT8(dev, CONC_bSKIPC_OFF, 0x10); 358 359 PUT8(dev, CONC_bSERFMT_OFF, tmp); 360 361 /* Set the frame count */ 362 audiopci_writemem(dev, CONC_ADCCTL_PAGE, CONC_wADCFC_OFF, 363 port->nframes - 1); 364 365 /* Set # of frames between interrupts */ 366 PUT16(dev, CONC_wADCIC_OFF, port->nframes - 1); 367 368 break; 369 } 370 371 port->frameno = 0; 372 } 373 374 static int 375 audiopci_open(void *arg, int flag, unsigned *nframes, caddr_t *bufp) 376 { 377 audiopci_port_t *port = arg; 378 379 _NOTE(ARGUNUSED(flag)); 380 381 /* NB: frame size = 4 (16-bit stereo) */ 382 port->nframes = AUDIOPCI_BUF_LEN / 4; 383 port->count = 0; 384 385 *nframes = port->nframes; 386 *bufp = port->kaddr; 387 388 return (0); 389 } 390 391 static int 392 audiopci_start(void *arg) 393 { 394 audiopci_port_t *port = arg; 395 audiopci_dev_t *dev = port->dev; 396 397 mutex_enter(&dev->mutex); 398 399 audiopci_init_port(port); 400 401 switch (port->num) { 402 case PORT_DAC: 403 SET8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_DAC_EN); 404 break; 405 case PORT_SYN: 406 SET8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_SYN_EN); 407 break; 408 case PORT_ADC: 409 SET8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_ADC_EN); 410 break; 411 } 412 mutex_exit(&dev->mutex); 413 414 return (0); 415 } 416 417 static void 418 audiopci_stop(void *arg) 419 { 420 audiopci_port_t *port = arg; 421 audiopci_dev_t *dev = port->dev; 422 423 mutex_enter(&dev->mutex); 424 switch (port->num) { 425 case PORT_DAC: 426 CLR8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_DAC_EN); 427 break; 428 case PORT_SYN: 429 CLR8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_SYN_EN); 430 break; 431 case PORT_ADC: 432 CLR8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_ADC_EN); 433 break; 434 } 435 mutex_exit(&dev->mutex); 436 } 437 438 static uint64_t 439 audiopci_count(void *arg) 440 { 441 audiopci_port_t *port = arg; 442 audiopci_dev_t *dev = port->dev; 443 uint64_t val; 444 uint32_t page, offs; 445 int frameno, n; 446 447 switch (port->num) { 448 case PORT_DAC: 449 page = CONC_DACCTL_PAGE; 450 offs = CONC_wDACFC_OFF; 451 break; 452 453 case PORT_SYN: 454 page = CONC_SYNCTL_PAGE; 455 offs = CONC_wSYNFC_OFF; 456 break; 457 458 case PORT_ADC: 459 page = CONC_ADCCTL_PAGE; 460 offs = CONC_wADCFC_OFF; 461 break; 462 } 463 464 /* 465 * Note that the current frame counter is in the high nybble. 466 */ 467 mutex_enter(&dev->mutex); 468 frameno = audiopci_readmem(port->dev, page, offs) >> 16; 469 mutex_exit(&dev->mutex); 470 471 n = frameno >= port->frameno ? 472 frameno - port->frameno : 473 frameno + port->nframes - port->frameno; 474 port->frameno = frameno; 475 port->count += n; 476 477 val = port->count; 478 return (val); 479 } 480 481 static void 482 audiopci_close(void *arg) 483 { 484 _NOTE(ARGUNUSED(arg)); 485 } 486 487 static void 488 audiopci_sync(void *arg, unsigned nframes) 489 { 490 audiopci_port_t *port = arg; 491 492 _NOTE(ARGUNUSED(nframes)); 493 494 if (port->num == PORT_ADC) { 495 (void) ddi_dma_sync(port->dmah, 0, 0, DDI_DMA_SYNC_FORCPU); 496 } else { 497 (void) ddi_dma_sync(port->dmah, 0, 0, DDI_DMA_SYNC_FORDEV); 498 } 499 } 500 501 audio_engine_ops_t audiopci_engine_ops = { 502 AUDIO_ENGINE_VERSION, /* version number */ 503 audiopci_open, 504 audiopci_close, 505 audiopci_start, 506 audiopci_stop, 507 audiopci_count, 508 audiopci_format, 509 audiopci_channels, 510 audiopci_rate, 511 audiopci_sync, 512 NULL, 513 NULL, 514 NULL, 515 }; 516 517 static uint16_t 518 audiopci_dac_rate(int samPerSec) 519 { 520 unsigned short usTemp; 521 522 /* samPerSec /= 2; */ 523 524 usTemp = (unsigned short) ((DAC_CLOCK_DIVIDE / 8) / samPerSec); 525 526 if (usTemp & 0x00000001) { 527 usTemp >>= 1; 528 usTemp -= 1; 529 } else { 530 usTemp >>= 1; 531 usTemp -= 2; 532 } 533 return (usTemp); 534 } 535 536 void 537 audiopci_init_hw(audiopci_dev_t *dev) 538 { 539 int tmp; 540 541 /* setup DAC frequency */ 542 PUT16(dev, CONC_wDACRATE_OFF, audiopci_dac_rate(48000)); 543 544 CLR8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_CCB_INTRM); 545 SET8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_SYN_44KHZ); 546 547 /* Turn on CODEC (UART and joystick left disabled) */ 548 tmp = GET8(dev, CONC_bDEVCTL_OFF); 549 tmp |= CONC_DEVCTL_SERR_DIS; 550 tmp |= CONC_DEVCTL_CODEC_EN; 551 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 552 553 /* Reset the UART */ 554 PUT8(dev, CONC_bUARTCSTAT_OFF, 0x00); 555 556 /* Disable NMI */ 557 PUT8(dev, CONC_bNMIENA_OFF, 0); 558 PUT16(dev, CONC_wNMISTAT_OFF, 0); 559 560 /* Initialize serial interface */ 561 PUT8(dev, CONC_bSERCTL_OFF, 0); 562 PUT8(dev, CONC_bSERFMT_OFF, 563 CONC_PCM_SYN_STEREO | CONC_PCM_SYN_16BIT); 564 565 /* Unmute codec */ 566 CLR8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_MUTE); 567 568 /* mixer initialization */ 569 audiopci_ak_idle(dev); 570 571 /* power/reset down the codec */ 572 audiopci_ak_write(dev, CODEC_RESET_PWRD, 0); 573 drv_usecwait(10); 574 575 /* now powerup and bring out of reset */ 576 audiopci_ak_write(dev, CODEC_RESET_PWRD, 0x3); 577 audiopci_ak_idle(dev); 578 579 /* enable PLL for DAC2 */ 580 audiopci_ak_write(dev, CODEC_CLKSELECT, 0); 581 582 /* select input mixer */ 583 audiopci_ak_write(dev, CODEC_ADSELECT, 0); 584 585 /* mark FM for output mixer */ 586 audiopci_ak_write(dev, CODEC_OUT_SW1, CODEC_OUT_ENABLE_SYNTH); 587 audiopci_ak_write(dev, CODEC_OUT_SW2, CODEC_OUT_ENABLE_WAVE); 588 589 /* initialize some reasonable values for the WAVE and SYNTH inputs */ 590 audiopci_ak_write(dev, CODEC_VOL_WAVE_L, 6); 591 audiopci_ak_write(dev, CODEC_VOL_WAVE_R, 6); 592 audiopci_ak_write(dev, CODEC_VOL_SYNTH_L, 6); 593 audiopci_ak_write(dev, CODEC_VOL_SYNTH_R, 6); 594 595 /* enable microphone phantom power */ 596 if (dev->micbias) { 597 SET16(dev, 2, CONC_DEVCTL_MICBIAS); 598 } 599 } 600 601 static int 602 audiopci_init(audiopci_dev_t *dev) 603 { 604 dev->micbias = 1; 605 606 audiopci_init_hw(dev); 607 608 for (int i = 0; i <= PORT_MAX; i++) { 609 audiopci_port_t *port; 610 unsigned caps; 611 unsigned dmaflags; 612 size_t rlen; 613 ddi_dma_cookie_t c; 614 unsigned ccnt; 615 616 port = &dev->port[i]; 617 port->dev = dev; 618 619 switch (i) { 620 case PORT_SYN: 621 caps = ENGINE_OUTPUT_CAP; 622 dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT; 623 port->speed = 44100; 624 break; 625 626 case PORT_DAC: 627 caps = ENGINE_OUTPUT_CAP; 628 dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT; 629 port->speed = 48000; 630 break; 631 632 case PORT_ADC: 633 caps = ENGINE_INPUT_CAP; 634 dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT; 635 port->speed = 48000; 636 break; 637 } 638 639 port->num = i; 640 641 /* 642 * Allocate DMA resources. 643 */ 644 645 if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_SLEEP, 646 NULL, &port->dmah) != DDI_SUCCESS) { 647 audio_dev_warn(dev->adev, 648 "port %d: dma handle allocation failed", i); 649 return (DDI_FAILURE); 650 } 651 if (ddi_dma_mem_alloc(port->dmah, AUDIOPCI_BUF_LEN, &buf_attr, 652 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &port->kaddr, 653 &rlen, &port->acch) != DDI_SUCCESS) { 654 audio_dev_warn(dev->adev, 655 "port %d: dma memory allocation failed", i); 656 return (DDI_FAILURE); 657 } 658 /* ensure that the buffer is zeroed out properly */ 659 bzero(port->kaddr, rlen); 660 if (ddi_dma_addr_bind_handle(port->dmah, NULL, port->kaddr, 661 AUDIOPCI_BUF_LEN, dmaflags, DDI_DMA_SLEEP, NULL, 662 &c, &ccnt) != DDI_DMA_MAPPED) { 663 audio_dev_warn(dev->adev, 664 "port %d: dma binding failed", i); 665 return (DDI_FAILURE); 666 } 667 port->paddr = c.dmac_address; 668 669 /* 670 * Allocate and configure audio engine. 671 */ 672 port->engine = audio_engine_alloc(&audiopci_engine_ops, caps); 673 if (port->engine == NULL) { 674 audio_dev_warn(dev->adev, 675 "port %d: audio_engine_alloc failed", i); 676 return (DDI_FAILURE); 677 } 678 679 audio_engine_set_private(port->engine, port); 680 audio_dev_add_engine(dev->adev, port->engine); 681 } 682 683 /* 684 * Register audio controls. 685 */ 686 if (audiopci_add_controls(dev) == DDI_FAILURE) { 687 return (DDI_FAILURE); 688 } 689 690 691 if (audio_dev_register(dev->adev) != DDI_SUCCESS) { 692 audio_dev_warn(dev->adev, 693 "unable to register with audio framework"); 694 return (DDI_FAILURE); 695 } 696 697 return (DDI_SUCCESS); 698 } 699 700 static void 701 audiopci_destroy(audiopci_dev_t *dev) 702 { 703 int i; 704 705 mutex_destroy(&dev->mutex); 706 707 /* free up ports, including DMA resources for ports */ 708 for (i = 0; i <= PORT_MAX; i++) { 709 audiopci_port_t *port = &dev->port[i]; 710 711 if (port->paddr != 0) 712 (void) ddi_dma_unbind_handle(port->dmah); 713 if (port->acch != NULL) 714 ddi_dma_mem_free(&port->acch); 715 if (port->dmah != NULL) 716 ddi_dma_free_handle(&port->dmah); 717 718 if (port->engine != NULL) { 719 audio_dev_remove_engine(dev->adev, port->engine); 720 audio_engine_free(port->engine); 721 } 722 } 723 724 if (dev->acch != NULL) { 725 ddi_regs_map_free(&dev->acch); 726 } 727 728 audiopci_del_controls(dev); 729 730 if (dev->adev != NULL) { 731 audio_dev_free(dev->adev); 732 } 733 734 kmem_free(dev, sizeof (*dev)); 735 } 736 737 static void 738 audiopci_stereo(audiopci_dev_t *dev, audiopci_ctrl_num_t num, uint8_t lreg) 739 { 740 uint8_t lval, rval; 741 uint8_t lmute, rmute; 742 uint64_t val; 743 uint8_t rreg; 744 745 rreg = lreg + 1; 746 val = dev->controls[num].val; 747 lval = (val & 0xff00) >> 8; 748 rval = val & 0xff; 749 750 lmute = lval ? 0 : CODEC_ATT_MUTE; 751 rmute = rval ? 0 : CODEC_ATT_MUTE; 752 753 /* convert to attenuation & apply mute if appropriate */ 754 lval = ((((100U - lval) * CODEC_ATT_MAX) / 100) & 0xff) | lmute; 755 rval = ((((100U - rval) * CODEC_ATT_MAX) / 100) & 0xff) | rmute; 756 757 audiopci_ak_write(dev, lreg, lval); 758 audiopci_ak_write(dev, rreg, rval); 759 } 760 761 static void 762 audiopci_mono(audiopci_dev_t *dev, audiopci_ctrl_num_t num, uint8_t reg) 763 { 764 uint64_t val = (dev->controls[num].val & 0xff); 765 uint8_t mute; 766 767 mute = val ? 0 : CODEC_ATT_MUTE; 768 val = ((((100U - val) * CODEC_ATT_MAX) / 100) & 0xff) | mute; 769 770 audiopci_ak_write(dev, reg, val); 771 } 772 773 static void 774 audiopci_mono8(audiopci_dev_t *dev, audiopci_ctrl_num_t num, uint8_t reg) 775 { 776 uint64_t val = (dev->controls[num].val & 0xff); 777 uint8_t mute; 778 779 mute = val ? 0 : CODEC_ATT_MUTE; 780 val = ((((100U - val) * CODEC_ATT_MONO) / 100) & 0xff) | mute; 781 782 audiopci_ak_write(dev, reg, val); 783 } 784 785 static int 786 audiopci_get_value(void *arg, uint64_t *val) 787 { 788 audiopci_ctrl_t *pc = arg; 789 790 *val = pc->val; 791 792 return (0); 793 } 794 795 static void 796 audiopci_configure_output(audiopci_dev_t *dev) 797 { 798 uint64_t val; 799 uint8_t tmp; 800 801 /* PCM/Wave level */ 802 audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_WAVE_L); 803 audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_WAVE_R); 804 audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_SYNTH_L); 805 audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_SYNTH_R); 806 807 /* front & mono outputs */ 808 audiopci_stereo(dev, CTL_FRONT, CODEC_VOL_MASTER_L); 809 audiopci_mono8(dev, CTL_MONO, CODEC_VOL_MONO); 810 811 val = dev->controls[CTL_MONSRC].val; 812 813 /* setup output monitoring as well */ 814 tmp = CODEC_OUT_ENABLE_SYNTH; 815 if (val & (1U << INPUT_MIC)) 816 tmp |= CODEC_OUT_ENABLE_MIC; 817 if (val & (1U << INPUT_CD)) 818 tmp |= CODEC_OUT_ENABLE_CD; 819 if (val & (1U << INPUT_LINEIN)) 820 tmp |= CODEC_OUT_ENABLE_AUX; 821 audiopci_ak_write(dev, CODEC_OUT_SW1, tmp); 822 823 tmp = CODEC_OUT_ENABLE_WAVE; 824 if (val & (1U << INPUT_VIDEO)) 825 tmp |= CODEC_OUT_ENABLE_TV; 826 if (val & (1U << INPUT_PHONE)) 827 tmp |= CODEC_OUT_ENABLE_TAD; 828 audiopci_ak_write(dev, CODEC_OUT_SW2, tmp); 829 } 830 831 static void 832 audiopci_configure_input(audiopci_dev_t *dev) 833 { 834 uint64_t val = dev->controls[CTL_RECSRC].val; 835 uint8_t tmp; 836 837 tmp = 0; 838 if (val & (1U << INPUT_LINEIN)) 839 tmp |= CODEC_IN_ENABLE_AUX_L; 840 if (val & (1U << INPUT_CD)) 841 tmp |= CODEC_IN_ENABLE_CD_L; 842 if (val & (1U << INPUT_MIC)) 843 tmp |= CODEC_IN_ENABLE_MIC; 844 if (val & (1U << INPUT_PHONE)) 845 tmp |= CODEC_IN_ENABLE_TAD; 846 audiopci_ak_write(dev, CODEC_LIN_SW1, tmp); 847 848 tmp = 0; 849 if (val & (1U << INPUT_LINEIN)) 850 tmp |= CODEC_IN_ENABLE_AUX_R; 851 if (val & (1U << INPUT_CD)) 852 tmp |= CODEC_IN_ENABLE_CD_R; 853 if (val & (1U << INPUT_PHONE)) 854 tmp |= CODEC_IN_ENABLE_TAD; 855 if (val & (1U << INPUT_MIC)) 856 tmp |= CODEC_IN_ENABLE_MIC; 857 audiopci_ak_write(dev, CODEC_RIN_SW1, tmp); 858 859 tmp = 0; 860 if (val & (1U << INPUT_VIDEO)) 861 tmp |= CODEC_IN_ENABLE_TV_L; 862 if (val & (1U << INPUT_MIC)) 863 tmp |= CODEC_IN_ENABLE_TMIC; 864 audiopci_ak_write(dev, CODEC_LIN_SW2, tmp); 865 866 tmp = 0; 867 if (val & (1U << INPUT_VIDEO)) 868 tmp |= CODEC_IN_ENABLE_TV_R; 869 if (val & (1U << INPUT_MIC)) 870 tmp |= CODEC_IN_ENABLE_TMIC; 871 audiopci_ak_write(dev, CODEC_RIN_SW2, tmp); 872 873 /* configure volumes */ 874 audiopci_mono(dev, CTL_MIC, CODEC_VOL_MIC); 875 audiopci_mono(dev, CTL_PHONE, CODEC_VOL_TAD); 876 audiopci_stereo(dev, CTL_LINE, CODEC_VOL_AUX_L); 877 audiopci_stereo(dev, CTL_CD, CODEC_VOL_CD_L); 878 audiopci_stereo(dev, CTL_VID, CODEC_VOL_TV_L); 879 880 /* activate 30dB mic boost */ 881 audiopci_ak_write(dev, CODEC_MICBOOST, 882 dev->controls[CTL_MICBOOST].val ? 1 : 0); 883 } 884 885 static int 886 audiopci_set_reclevel(void *arg, uint64_t val) 887 { 888 audiopci_ctrl_t *pc = arg; 889 audiopci_dev_t *dev = pc->dev; 890 uint8_t l; 891 uint8_t r; 892 893 l = (val & 0xff00) >> 8; 894 r = val & 0xff; 895 896 if ((l > 100) || (r > 100)) 897 return (EINVAL); 898 899 mutex_enter(&dev->mutex); 900 pc->val = val; 901 audiopci_configure_input(dev); 902 903 mutex_exit(&dev->mutex); 904 return (0); 905 } 906 907 static int 908 audiopci_set_micboost(void *arg, uint64_t val) 909 { 910 audiopci_ctrl_t *pc = arg; 911 audiopci_dev_t *dev = pc->dev; 912 913 mutex_enter(&dev->mutex); 914 pc->val = val; 915 audiopci_configure_input(dev); 916 mutex_exit(&dev->mutex); 917 return (0); 918 } 919 920 static int 921 audiopci_set_monsrc(void *arg, uint64_t val) 922 { 923 audiopci_ctrl_t *pc = arg; 924 audiopci_dev_t *dev = pc->dev; 925 926 if ((val & ~INSRCS) != 0) 927 return (EINVAL); 928 929 mutex_enter(&dev->mutex); 930 pc->val = val; 931 audiopci_configure_output(dev); 932 mutex_exit(&dev->mutex); 933 return (0); 934 } 935 936 static int 937 audiopci_set_recsrc(void *arg, uint64_t val) 938 { 939 audiopci_ctrl_t *pc = arg; 940 audiopci_dev_t *dev = pc->dev; 941 942 if ((val & ~INSRCS) != 0) 943 return (EINVAL); 944 945 mutex_enter(&dev->mutex); 946 pc->val = val; 947 audiopci_configure_input(dev); 948 mutex_exit(&dev->mutex); 949 return (0); 950 } 951 952 static int 953 audiopci_set_volume(void *arg, uint64_t val) 954 { 955 audiopci_ctrl_t *pc = arg; 956 audiopci_dev_t *dev = pc->dev; 957 958 val &= 0xff; 959 if (val > 100) 960 return (EINVAL); 961 962 val = (val & 0xff) | ((val & 0xff) << 8); 963 964 mutex_enter(&dev->mutex); 965 pc->val = val; 966 audiopci_configure_output(dev); 967 mutex_exit(&dev->mutex); 968 969 return (0); 970 } 971 972 static int 973 audiopci_set_front(void *arg, uint64_t val) 974 { 975 audiopci_ctrl_t *pc = arg; 976 audiopci_dev_t *dev = pc->dev; 977 uint8_t l; 978 uint8_t r; 979 980 l = (val & 0xff00) >> 8; 981 r = val & 0xff; 982 983 if ((l > 100) || (r > 100)) 984 return (EINVAL); 985 986 mutex_enter(&dev->mutex); 987 pc->val = val; 988 audiopci_configure_output(dev); 989 990 mutex_exit(&dev->mutex); 991 return (0); 992 } 993 994 static int 995 audiopci_set_speaker(void *arg, uint64_t val) 996 { 997 audiopci_ctrl_t *pc = arg; 998 audiopci_dev_t *dev = pc->dev; 999 1000 val &= 0xff; 1001 1002 if (val > 100) 1003 return (EINVAL); 1004 1005 mutex_enter(&dev->mutex); 1006 pc->val = val; 1007 audiopci_configure_output(dev); 1008 1009 mutex_exit(&dev->mutex); 1010 return (0); 1011 } 1012 1013 #define PLAYCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY) 1014 #define RECCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC) 1015 #define MONCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR) 1016 #define PCMVOL (PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL) 1017 #define MAINVOL (PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL) 1018 #define RECVOL (RECCTL | AUDIO_CTRL_FLAG_RECVOL) 1019 1020 static void 1021 audiopci_alloc_ctrl(audiopci_dev_t *dev, uint32_t num, uint64_t val) 1022 { 1023 audio_ctrl_desc_t desc; 1024 audio_ctrl_wr_t fn; 1025 audiopci_ctrl_t *pc; 1026 1027 bzero(&desc, sizeof (desc)); 1028 1029 pc = &dev->controls[num]; 1030 pc->num = num; 1031 pc->dev = dev; 1032 1033 switch (num) { 1034 case CTL_VOLUME: 1035 desc.acd_name = AUDIO_CTRL_ID_VOLUME; 1036 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 1037 desc.acd_minvalue = 0; 1038 desc.acd_maxvalue = 100; 1039 desc.acd_flags = PCMVOL; 1040 fn = audiopci_set_volume; 1041 break; 1042 1043 case CTL_FRONT: 1044 desc.acd_name = AUDIO_CTRL_ID_LINEOUT; 1045 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1046 desc.acd_minvalue = 0; 1047 desc.acd_maxvalue = 100; 1048 desc.acd_flags = MAINVOL; 1049 fn = audiopci_set_front; 1050 break; 1051 1052 case CTL_MONO: 1053 desc.acd_name = AUDIO_CTRL_ID_SPEAKER; 1054 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 1055 desc.acd_minvalue = 0; 1056 desc.acd_maxvalue = 100; 1057 desc.acd_flags = MAINVOL; 1058 fn = audiopci_set_speaker; 1059 break; 1060 1061 case CTL_MIC: 1062 desc.acd_name = AUDIO_CTRL_ID_MIC; 1063 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 1064 desc.acd_minvalue = 0; 1065 desc.acd_maxvalue = 100; 1066 desc.acd_flags = RECVOL; 1067 fn = audiopci_set_reclevel; 1068 break; 1069 1070 case CTL_LINE: 1071 desc.acd_name = AUDIO_CTRL_ID_LINEIN; 1072 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1073 desc.acd_minvalue = 0; 1074 desc.acd_maxvalue = 100; 1075 desc.acd_flags = RECVOL; 1076 fn = audiopci_set_reclevel; 1077 break; 1078 1079 case CTL_CD: 1080 desc.acd_name = AUDIO_CTRL_ID_CD; 1081 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1082 desc.acd_minvalue = 0; 1083 desc.acd_maxvalue = 100; 1084 desc.acd_flags = RECVOL; 1085 fn = audiopci_set_reclevel; 1086 break; 1087 1088 case CTL_VID: 1089 desc.acd_name = AUDIO_CTRL_ID_VIDEO; 1090 desc.acd_type = AUDIO_CTRL_TYPE_STEREO; 1091 desc.acd_minvalue = 0; 1092 desc.acd_maxvalue = 100; 1093 desc.acd_flags = RECVOL; 1094 fn = audiopci_set_reclevel; 1095 break; 1096 1097 case CTL_PHONE: 1098 desc.acd_name = AUDIO_CTRL_ID_PHONE; 1099 desc.acd_type = AUDIO_CTRL_TYPE_MONO; 1100 desc.acd_minvalue = 0; 1101 desc.acd_maxvalue = 100; 1102 desc.acd_flags = RECVOL; 1103 fn = audiopci_set_reclevel; 1104 break; 1105 1106 case CTL_RECSRC: 1107 desc.acd_name = AUDIO_CTRL_ID_RECSRC; 1108 desc.acd_type = AUDIO_CTRL_TYPE_ENUM; 1109 desc.acd_minvalue = INSRCS; 1110 desc.acd_maxvalue = INSRCS; 1111 desc.acd_flags = RECCTL | AUDIO_CTRL_FLAG_MULTI; 1112 for (int i = 0; audiopci_insrcs[i]; i++) { 1113 desc.acd_enum[i] = audiopci_insrcs[i]; 1114 } 1115 fn = audiopci_set_recsrc; 1116 break; 1117 1118 case CTL_MONSRC: 1119 desc.acd_name = AUDIO_CTRL_ID_MONSRC; 1120 desc.acd_type = AUDIO_CTRL_TYPE_ENUM; 1121 desc.acd_minvalue = INSRCS; 1122 desc.acd_maxvalue = INSRCS; 1123 desc.acd_flags = MONCTL | AUDIO_CTRL_FLAG_MULTI; 1124 for (int i = 0; audiopci_insrcs[i]; i++) { 1125 desc.acd_enum[i] = audiopci_insrcs[i]; 1126 } 1127 fn = audiopci_set_monsrc; 1128 break; 1129 1130 case CTL_MICBOOST: 1131 desc.acd_name = AUDIO_CTRL_ID_MICBOOST; 1132 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN; 1133 desc.acd_minvalue = 0; 1134 desc.acd_maxvalue = 100; 1135 desc.acd_flags = RECCTL; 1136 fn = audiopci_set_micboost; 1137 break; 1138 } 1139 1140 pc->val = val; 1141 pc->ctrl = audio_dev_add_control(dev->adev, &desc, 1142 audiopci_get_value, fn, pc); 1143 } 1144 1145 static int 1146 audiopci_add_controls(audiopci_dev_t *dev) 1147 { 1148 audiopci_alloc_ctrl(dev, CTL_VOLUME, 75); 1149 audiopci_alloc_ctrl(dev, CTL_FRONT, ((75) | (75 << 8))); 1150 audiopci_alloc_ctrl(dev, CTL_MONO, 75); 1151 audiopci_alloc_ctrl(dev, CTL_MIC, 50); 1152 audiopci_alloc_ctrl(dev, CTL_LINE, 0); 1153 audiopci_alloc_ctrl(dev, CTL_CD, 0); 1154 audiopci_alloc_ctrl(dev, CTL_VID, 0); 1155 audiopci_alloc_ctrl(dev, CTL_PHONE, 0); 1156 audiopci_alloc_ctrl(dev, CTL_RECSRC, (1U << INPUT_MIC)); 1157 audiopci_alloc_ctrl(dev, CTL_MONSRC, 0); 1158 audiopci_alloc_ctrl(dev, CTL_MICBOOST, 1); 1159 1160 audiopci_configure_output(dev); 1161 audiopci_configure_input(dev); 1162 1163 return (DDI_SUCCESS); 1164 } 1165 1166 static void 1167 audiopci_del_controls(audiopci_dev_t *dev) 1168 { 1169 for (int i = 0; i < CTL_NUM; i++) { 1170 if (dev->controls[i].ctrl) { 1171 audio_dev_del_control(dev->controls[i].ctrl); 1172 } 1173 } 1174 } 1175 1176 static int 1177 audiopci_attach(dev_info_t *dip) 1178 { 1179 uint16_t pci_command, vendor, device; 1180 audiopci_dev_t *dev; 1181 ddi_acc_handle_t pcih; 1182 1183 dev = kmem_zalloc(sizeof (*dev), KM_SLEEP); 1184 dev->dip = dip; 1185 ddi_set_driver_private(dip, dev); 1186 1187 mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, NULL); 1188 1189 if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) { 1190 audio_dev_warn(dev->adev, "pci_config_setup failed"); 1191 mutex_destroy(&dev->mutex); 1192 kmem_free(dev, sizeof (*dev)); 1193 return (DDI_FAILURE); 1194 } 1195 1196 vendor = pci_config_get16(pcih, PCI_CONF_VENID); 1197 device = pci_config_get16(pcih, PCI_CONF_DEVID); 1198 1199 if ((vendor != ENSONIQ_VENDOR_ID && vendor != CREATIVE_VENDOR_ID) || 1200 (device != ENSONIQ_ES1370)) 1201 goto err_exit; 1202 1203 dev->devid = device; 1204 1205 dev->adev = audio_dev_alloc(dip, 0); 1206 if (dev->adev == NULL) { 1207 goto err_exit; 1208 } 1209 1210 audio_dev_set_description(dev->adev, "AudioPCI"); 1211 audio_dev_set_version(dev->adev, "ES1370"); 1212 audio_dev_add_info(dev->adev, "Legacy codec: Asahi Kasei AK4531"); 1213 1214 /* activate the device */ 1215 pci_command = pci_config_get16(pcih, PCI_CONF_COMM); 1216 pci_command |= PCI_COMM_ME | PCI_COMM_IO; 1217 pci_config_put16(pcih, PCI_CONF_COMM, pci_command); 1218 1219 /* map registers */ 1220 if (ddi_regs_map_setup(dip, 1, &dev->regs, 0, 0, &acc_attr, 1221 &dev->acch) != DDI_SUCCESS) { 1222 audio_dev_warn(dev->adev, "can't map registers"); 1223 goto err_exit; 1224 } 1225 1226 1227 /* This allocates and configures the engines */ 1228 if (audiopci_init(dev) != DDI_SUCCESS) { 1229 audio_dev_warn(dev->adev, "can't init device"); 1230 goto err_exit; 1231 } 1232 1233 pci_config_teardown(&pcih); 1234 1235 ddi_report_dev(dip); 1236 1237 return (DDI_SUCCESS); 1238 1239 err_exit: 1240 mutex_destroy(&dev->mutex); 1241 pci_config_teardown(&pcih); 1242 1243 audiopci_destroy(dev); 1244 1245 return (DDI_FAILURE); 1246 } 1247 1248 static int 1249 audiopci_detach(audiopci_dev_t *dev) 1250 { 1251 int tmp; 1252 1253 /* first unregister us from the DDI framework, might be busy */ 1254 if (audio_dev_unregister(dev->adev) != DDI_SUCCESS) 1255 return (DDI_FAILURE); 1256 1257 mutex_enter(&dev->mutex); 1258 1259 tmp = GET8(dev, CONC_bSERCTL_OFF) & 1260 ~(CONC_SERCTL_DACIE | CONC_SERCTL_SYNIE | CONC_SERCTL_ADCIE); 1261 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1262 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1263 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1264 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1265 1266 tmp = GET8(dev, CONC_bDEVCTL_OFF) & 1267 ~(CONC_DEVCTL_DAC_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_SYN_EN); 1268 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1269 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1270 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1271 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1272 1273 mutex_exit(&dev->mutex); 1274 1275 audiopci_destroy(dev); 1276 1277 return (DDI_SUCCESS); 1278 } 1279 1280 static int 1281 audiopci_resume(audiopci_dev_t *dev) 1282 { 1283 /* reinitialize hardware */ 1284 audiopci_init_hw(dev); 1285 1286 audio_dev_resume(dev->adev); 1287 return (DDI_SUCCESS); 1288 } 1289 1290 static int 1291 audiopci_suspend(audiopci_dev_t *dev) 1292 { 1293 audio_dev_suspend(dev->adev); 1294 1295 return (DDI_SUCCESS); 1296 } 1297 1298 static int 1299 audiopci_quiesce(dev_info_t *dip) 1300 { 1301 audiopci_dev_t *dev; 1302 uint8_t tmp; 1303 1304 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1305 return (DDI_FAILURE); 1306 } 1307 1308 /* This disables all DMA engines and interrupts */ 1309 tmp = GET8(dev, CONC_bSERCTL_OFF) & 1310 ~(CONC_SERCTL_DACIE | CONC_SERCTL_SYNIE | CONC_SERCTL_ADCIE); 1311 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1312 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1313 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1314 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1315 1316 tmp = GET8(dev, CONC_bDEVCTL_OFF) & 1317 ~(CONC_DEVCTL_DAC_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_SYN_EN); 1318 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1319 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1320 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1321 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1322 1323 return (DDI_SUCCESS); 1324 } 1325 1326 1327 static int 1328 audiopci_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1329 { 1330 audiopci_dev_t *dev; 1331 1332 switch (cmd) { 1333 case DDI_ATTACH: 1334 return (audiopci_attach(dip)); 1335 1336 case DDI_RESUME: 1337 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1338 return (DDI_FAILURE); 1339 } 1340 return (audiopci_resume(dev)); 1341 1342 default: 1343 return (DDI_FAILURE); 1344 } 1345 } 1346 1347 static int 1348 audiopci_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1349 { 1350 audiopci_dev_t *dev; 1351 1352 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1353 return (DDI_FAILURE); 1354 } 1355 1356 switch (cmd) { 1357 case DDI_DETACH: 1358 return (audiopci_detach(dev)); 1359 1360 case DDI_SUSPEND: 1361 return (audiopci_suspend(dev)); 1362 default: 1363 return (DDI_FAILURE); 1364 } 1365 } 1366 1367 static struct dev_ops audiopci_dev_ops = { 1368 DEVO_REV, /* rev */ 1369 0, /* refcnt */ 1370 NULL, /* getinfo */ 1371 nulldev, /* identify */ 1372 nulldev, /* probe */ 1373 audiopci_ddi_attach, /* attach */ 1374 audiopci_ddi_detach, /* detach */ 1375 nodev, /* reset */ 1376 NULL, /* cb_ops */ 1377 NULL, /* bus_ops */ 1378 NULL, /* power */ 1379 audiopci_quiesce, /* quiesce */ 1380 }; 1381 1382 static struct modldrv audiopci_modldrv = { 1383 &mod_driverops, /* drv_modops */ 1384 "Ensoniq 1370 Audio", /* linkinfo */ 1385 &audiopci_dev_ops, /* dev_ops */ 1386 }; 1387 1388 static struct modlinkage modlinkage = { 1389 MODREV_1, 1390 { &audiopci_modldrv, NULL } 1391 }; 1392 1393 int 1394 _init(void) 1395 { 1396 int rv; 1397 1398 audio_init_ops(&audiopci_dev_ops, DRVNAME); 1399 if ((rv = mod_install(&modlinkage)) != 0) { 1400 audio_fini_ops(&audiopci_dev_ops); 1401 } 1402 return (rv); 1403 } 1404 1405 int 1406 _fini(void) 1407 { 1408 int rv; 1409 1410 if ((rv = mod_remove(&modlinkage)) == 0) { 1411 audio_fini_ops(&audiopci_dev_ops); 1412 } 1413 return (rv); 1414 } 1415 1416 int 1417 _info(struct modinfo *modinfop) 1418 { 1419 return (mod_info(&modlinkage, modinfop)); 1420 } 1421