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: Creative/Ensoniq AudioPCI97 driver (ES1371/ES1373) 27 * 28 * This driver is used with the original Ensoniq AudioPCI97 card and many 29 * PCI based Sound Blaster cards by Creative Technologies. For example 30 * Sound Blaster PCI128 and Creative/Ectiva EV1938. 31 */ 32 33 /* 34 * This file is part of Open Sound System 35 * 36 * Copyright (C) 4Front Technologies 1996-2008. 37 * 38 * This software is released under CDDL 1.0 source license. 39 * See the COPYING file included in the main directory of this source 40 * distribution for the license terms and conditions. 41 */ 42 43 #include <sys/audio/audio_driver.h> 44 #include <sys/audio/ac97.h> 45 #include <sys/note.h> 46 #include <sys/pci.h> 47 #include "audioens.h" 48 49 /* 50 * The original OSS driver used a single duplex engine and a separate 51 * playback only engine. Instead, we expose three engines, one for input 52 * and two for output. 53 */ 54 55 /* 56 * Set the latency to 32, 64, 96, 128 clocks - some APCI97 devices exhibit 57 * garbled audio in some cases and setting the latency to higer values fixes it 58 * Values: 32, 64, 96, 128 - Default: 64 (or defined by bios) 59 */ 60 int audioens_latency = 0; 61 62 /* 63 * Enable SPDIF port on SoundBlaster 128D or Sound Blaster Digital-4.1 models 64 * Values: 1=Enable 0=Disable Default: 0 65 */ 66 int audioens_spdif = 0; 67 68 /* 69 * Note: Latest devices can support SPDIF with AC3 pass thru. 70 * However, in order to do this, one of the two DMA engines must be 71 * dedicated to this, which would prevent the card from supporting 4 72 * channel audio. For now we don't bother with the AC3 pass through 73 * mode, and instead just focus on 4 channel support. In the future, 74 * this could be selectable via a property. 75 */ 76 77 #define ENSONIQ_VENDOR_ID 0x1274 78 #define CREATIVE_VENDOR_ID 0x1102 79 #define ECTIVA_VENDOR_ID 0x1102 80 #define ENSONIQ_ES1371 0x1371 81 #define ENSONIQ_ES5880 0x8001 82 #define ENSONIQ_ES5880A 0x8002 83 #define ENSONIQ_ES5880B 0x5880 84 #define ECTIVA_ES1938 0x8938 85 86 #define DEFRATE 48000 87 #define DEFINTS 75 88 #define DRVNAME "audioens" 89 90 typedef struct audioens_port 91 { 92 /* Audio parameters */ 93 boolean_t trigger; 94 boolean_t suspended; 95 96 int speed; 97 98 int num; 99 #define PORT_DAC 0 100 #define PORT_ADC 1 101 #define PORT_MAX PORT_ADC 102 103 caddr_t kaddr; 104 uint32_t paddr; 105 ddi_acc_handle_t acch; 106 ddi_dma_handle_t dmah; 107 int nchan; 108 unsigned fragfr; 109 unsigned nfrags; 110 unsigned nframes; 111 unsigned frameno; 112 uint64_t count; 113 114 struct audioens_dev *dev; 115 audio_engine_t *engine; 116 } audioens_port_t; 117 118 typedef struct audioens_dev 119 { 120 audio_dev_t *osdev; 121 kmutex_t mutex; 122 uint16_t devid; 123 uint8_t revision; 124 dev_info_t *dip; 125 boolean_t enabled; 126 127 128 int pintrs; 129 int rintrs; 130 131 kstat_t *ksp; 132 133 audioens_port_t port[PORT_MAX + 1]; 134 135 ac97_t *ac97; 136 137 caddr_t regs; 138 ddi_acc_handle_t acch; 139 ddi_intr_handle_t ihandle[1]; 140 } audioens_dev_t; 141 142 static ddi_device_acc_attr_t acc_attr = { 143 DDI_DEVICE_ATTR_V0, 144 DDI_STRUCTURE_LE_ACC, 145 DDI_STRICTORDER_ACC 146 }; 147 148 static ddi_device_acc_attr_t buf_attr = { 149 DDI_DEVICE_ATTR_V0, 150 DDI_NEVERSWAP_ACC, 151 DDI_STRICTORDER_ACC 152 }; 153 154 /* 155 * The hardware appears to be able to address up to 16-bits worth of longwords, 156 * giving a total address space of 256K. Note, however, that we will restrict 157 * this further when we do fragment and memory allocation. At its very highest 158 * clock rate (48 kHz) and sample size (16-bit stereo), and lowest interrupt 159 * rate (32 Hz), we only need 6000 bytes per fragment. 160 * 161 * So with an allocated buffer size of 64K, we can support at least 10 frags, 162 * which is more than enough. (The legacy Sun driver used only 2 fragments.) 163 */ 164 #define AUDIOENS_BUF_LEN (65536) 165 166 static ddi_dma_attr_t dma_attr = { 167 DMA_ATTR_VERSION, /* dma_attr_version */ 168 0x0, /* dma_attr_addr_lo */ 169 0xffffffffU, /* dma_attr_addr_hi */ 170 0x3ffff, /* dma_attr_count_max */ 171 0x8, /* dma_attr_align */ 172 0x7f, /* dma_attr_burstsizes */ 173 0x1, /* dma_attr_minxfer */ 174 0x3ffff, /* dma_attr_maxxfer */ 175 0x3ffff, /* dma_attr_seg */ 176 0x1, /* dma_attr_sgllen */ 177 0x1, /* dma_attr_granular */ 178 0 /* dma_attr_flags */ 179 }; 180 181 #define GET8(dev, offset) \ 182 ddi_get8(dev->acch, (uint8_t *)(dev->regs + (offset))) 183 #define GET16(dev, offset) \ 184 ddi_get16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset))) 185 #define GET32(dev, offset) \ 186 ddi_get32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset))) 187 #define PUT8(dev, offset, v) \ 188 ddi_put8(dev->acch, (uint8_t *)(dev->regs + (offset)), v) 189 #define PUT16(dev, offset, v) \ 190 ddi_put16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)), v) 191 #define PUT32(dev, offset, v) \ 192 ddi_put32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)), v) 193 194 #define CLR8(dev, offset, v) PUT8(dev, offset, GET8(dev, offset) & ~(v)) 195 #define SET8(dev, offset, v) PUT8(dev, offset, GET8(dev, offset) | (v)) 196 #define CLR32(dev, offset, v) PUT32(dev, offset, GET32(dev, offset) & ~(v)) 197 #define SET32(dev, offset, v) PUT32(dev, offset, GET32(dev, offset) | (v)) 198 199 #define KSINTR(dev) ((kstat_intr_t *)((dev)->ksp->ks_data)) 200 201 static void audioens_init_hw(audioens_dev_t *); 202 static void audioens_init_port(audioens_port_t *); 203 static void audioens_start_port(audioens_port_t *); 204 static void audioens_stop_port(audioens_port_t *); 205 static void audioens_update_port(audioens_port_t *); 206 207 static uint16_t 208 audioens_rd97(void *dev_, uint8_t wAddr) 209 { 210 audioens_dev_t *dev = dev_; 211 int i, dtemp; 212 213 mutex_enter(&dev->mutex); 214 dtemp = GET32(dev, CONC_dCODECCTL_OFF); 215 /* wait for WIP to go away saving the current state for later */ 216 for (i = 0; i < 0x100UL; ++i) { 217 dtemp = GET32(dev, CONC_dCODECCTL_OFF); 218 if ((dtemp & (1UL << 30)) == 0) 219 break; 220 } 221 222 /* write addr w/data=0 and assert read request ... */ 223 PUT32(dev, CONC_dCODECCTL_OFF, ((int)wAddr << 16) | (1UL << 23)); 224 225 /* now wait for the data (RDY) */ 226 for (i = 0; i < 0x100UL; ++i) { 227 dtemp = GET32(dev, CONC_dCODECCTL_OFF); 228 if (dtemp & (1UL << 31)) 229 break; 230 } 231 dtemp = GET32(dev, CONC_dCODECCTL_OFF); 232 mutex_exit(&dev->mutex); 233 234 return (dtemp & 0xffff); 235 } 236 237 static void 238 audioens_wr97(void *dev_, uint8_t wAddr, uint16_t wData) 239 { 240 audioens_dev_t *dev = dev_; 241 int i, dtemp; 242 243 mutex_enter(&dev->mutex); 244 /* wait for WIP to go away */ 245 for (i = 0; i < 0x100UL; ++i) { 246 dtemp = GET32(dev, CONC_dCODECCTL_OFF); 247 if ((dtemp & (1UL << 30)) == 0) 248 break; 249 } 250 251 PUT32(dev, CONC_dCODECCTL_OFF, ((int)wAddr << 16) | wData); 252 253 mutex_exit(&dev->mutex); 254 } 255 256 static unsigned short 257 SRCRegRead(audioens_dev_t *dev, unsigned short reg) 258 { 259 int i, dtemp; 260 261 dtemp = GET32(dev, CONC_dSRCIO_OFF); 262 /* wait for ready */ 263 for (i = 0; i < SRC_IOPOLL_COUNT; ++i) { 264 dtemp = GET32(dev, CONC_dSRCIO_OFF); 265 if ((dtemp & SRC_BUSY) == 0) 266 break; 267 } 268 269 /* assert a read request */ 270 PUT32(dev, CONC_dSRCIO_OFF, (dtemp & SRC_CTLMASK) | ((int)reg << 25)); 271 272 /* now wait for the data */ 273 for (i = 0; i < SRC_IOPOLL_COUNT; ++i) { 274 dtemp = GET32(dev, CONC_dSRCIO_OFF); 275 if ((dtemp & SRC_BUSY) == 0) 276 break; 277 } 278 279 return ((unsigned short) dtemp); 280 } 281 282 static void 283 SRCRegWrite(audioens_dev_t *dev, unsigned short reg, unsigned short val) 284 { 285 int i, dtemp; 286 int writeval; 287 288 dtemp = GET32(dev, CONC_dSRCIO_OFF); 289 /* wait for ready */ 290 for (i = 0; i < SRC_IOPOLL_COUNT; ++i) { 291 dtemp = GET32(dev, CONC_dSRCIO_OFF); 292 if ((dtemp & SRC_BUSY) == 0) 293 break; 294 } 295 296 /* assert the write request */ 297 writeval = (dtemp & SRC_CTLMASK) | SRC_WENABLE | 298 ((int)reg << 25) | val; 299 PUT32(dev, CONC_dSRCIO_OFF, writeval); 300 } 301 302 static void 303 SRCSetRate(audioens_dev_t *dev, unsigned char base, unsigned short rate) 304 { 305 int i, freq, dtemp; 306 unsigned short N, truncM, truncStart; 307 308 if (base != SRC_ADC_BASE) { 309 /* freeze the channel */ 310 dtemp = (base == SRC_DAC1_BASE) ? 311 SRC_DAC1FREEZE : SRC_DAC2FREEZE; 312 for (i = 0; i < SRC_IOPOLL_COUNT; ++i) { 313 if (!(GET32(dev, CONC_dSRCIO_OFF) & SRC_BUSY)) 314 break; 315 } 316 PUT32(dev, CONC_dSRCIO_OFF, 317 (GET32(dev, CONC_dSRCIO_OFF) & SRC_CTLMASK) | dtemp); 318 319 /* calculate new frequency and write it - preserve accum */ 320 freq = ((int)rate << 16) / 3000U; 321 SRCRegWrite(dev, (unsigned short) base + SRC_INT_REGS_OFF, 322 (SRCRegRead(dev, (unsigned short) base + SRC_INT_REGS_OFF) 323 & 0x00ffU) | ((unsigned short) (freq >> 6) & 0xfc00)); 324 SRCRegWrite(dev, (unsigned short) base + SRC_VFREQ_FRAC_OFF, 325 (unsigned short) freq >> 1); 326 327 /* un-freeze the channel */ 328 for (i = 0; i < SRC_IOPOLL_COUNT; ++i) 329 if (!(GET32(dev, CONC_dSRCIO_OFF) & SRC_BUSY)) 330 break; 331 PUT32(dev, CONC_dSRCIO_OFF, 332 (GET32(dev, CONC_dSRCIO_OFF) & SRC_CTLMASK) & ~dtemp); 333 } else { 334 /* derive oversample ratio */ 335 N = rate / 3000U; 336 if (N == 15 || N == 13 || N == 11 || N == 9) 337 --N; 338 339 /* truncate the filter and write n/trunc_start */ 340 truncM = (21 * N - 1) | 1; 341 if (rate >= 24000U) { 342 if (truncM > 239) 343 truncM = 239; 344 truncStart = (239 - truncM) >> 1; 345 346 SRCRegWrite(dev, base + SRC_TRUNC_N_OFF, 347 (truncStart << 9) | (N << 4)); 348 } else { 349 if (truncM > 119) 350 truncM = 119; 351 truncStart = (119 - truncM) >> 1; 352 353 SRCRegWrite(dev, base + SRC_TRUNC_N_OFF, 354 0x8000U | (truncStart << 9) | (N << 4)); 355 } 356 357 /* calculate new frequency and write it - preserve accum */ 358 freq = ((48000UL << 16) / rate) * N; 359 SRCRegWrite(dev, base + SRC_INT_REGS_OFF, 360 (SRCRegRead(dev, (unsigned short) base + SRC_INT_REGS_OFF) 361 & 0x00ff) | ((unsigned short) (freq >> 6) & 0xfc00)); 362 SRCRegWrite(dev, base + SRC_VFREQ_FRAC_OFF, 363 (unsigned short) freq >> 1); 364 365 SRCRegWrite(dev, SRC_ADC_VOL_L, N << 8); 366 SRCRegWrite(dev, SRC_ADC_VOL_R, N << 8); 367 } 368 } 369 370 static void 371 SRCInit(audioens_dev_t *dev) 372 { 373 int i; 374 375 /* Clear all SRC RAM then init - keep SRC disabled until done */ 376 for (i = 0; i < SRC_IOPOLL_COUNT; ++i) { 377 if (!(GET32(dev, CONC_dSRCIO_OFF) & SRC_BUSY)) 378 break; 379 } 380 PUT32(dev, CONC_dSRCIO_OFF, SRC_DISABLE); 381 382 for (i = 0; i < 0x80; ++i) 383 SRCRegWrite(dev, (unsigned short) i, 0U); 384 385 SRCRegWrite(dev, SRC_DAC1_BASE + SRC_TRUNC_N_OFF, 16 << 4); 386 SRCRegWrite(dev, SRC_DAC1_BASE + SRC_INT_REGS_OFF, 16 << 10); 387 SRCRegWrite(dev, SRC_DAC2_BASE + SRC_TRUNC_N_OFF, 16 << 4); 388 SRCRegWrite(dev, SRC_DAC2_BASE + SRC_INT_REGS_OFF, 16 << 10); 389 SRCRegWrite(dev, SRC_DAC1_VOL_L, 1 << 12); 390 SRCRegWrite(dev, SRC_DAC1_VOL_R, 1 << 12); 391 SRCRegWrite(dev, SRC_DAC2_VOL_L, 1 << 12); 392 SRCRegWrite(dev, SRC_DAC2_VOL_R, 1 << 12); 393 SRCRegWrite(dev, SRC_ADC_VOL_L, 1 << 12); 394 SRCRegWrite(dev, SRC_ADC_VOL_R, 1 << 12); 395 396 /* default some rates */ 397 SRCSetRate(dev, SRC_DAC1_BASE, 48000); 398 SRCSetRate(dev, SRC_DAC2_BASE, 48000); 399 SRCSetRate(dev, SRC_ADC_BASE, 48000); 400 401 /* now enable the whole deal */ 402 for (i = 0; i < SRC_IOPOLL_COUNT; ++i) { 403 if (!(GET32(dev, CONC_dSRCIO_OFF) & SRC_BUSY)) 404 break; 405 } 406 PUT32(dev, CONC_dSRCIO_OFF, 0); 407 } 408 409 static void 410 audioens_writemem(audioens_dev_t *dev, uint32_t page, uint32_t offs, 411 uint32_t data) 412 { 413 /* Select memory page */ 414 PUT32(dev, CONC_bMEMPAGE_OFF, page); 415 PUT32(dev, offs, data); 416 } 417 418 static uint32_t 419 audioens_readmem(audioens_dev_t *dev, uint32_t page, uint32_t offs) 420 { 421 PUT32(dev, CONC_bMEMPAGE_OFF, page); /* Select memory page */ 422 return (GET32(dev, offs)); 423 } 424 425 static uint_t 426 audioens_intr(caddr_t arg1, caddr_t arg2) 427 { 428 audioens_dev_t *dev = (void *)arg1; 429 int stats; 430 int tmp; 431 unsigned char ackbits = 0; 432 audioens_port_t *port; 433 audio_engine_t *do_dac, *do_adc; 434 435 _NOTE(ARGUNUSED(arg2)); 436 437 /* 438 * NB: The old audioens didn't report spurious interrupts. On 439 * a system with shared interrupts (typical!) there will 440 * normally be lots of these (each time the "other" device 441 * interrupts). 442 * 443 * Also, because of the way the interrupt chain handling 444 * works, reporting of spurious interrupts is probably not 445 * terribly useful. 446 * 447 * However, we can count interrupts where the master interrupt 448 * bit is set but none of the ackbits that we are prepared to 449 * process is set. That is probably useful. 450 */ 451 mutex_enter(&dev->mutex); 452 if (!dev->enabled) { 453 454 mutex_exit(&dev->mutex); 455 return (DDI_INTR_UNCLAIMED); 456 } 457 458 stats = GET32(dev, CONC_dSTATUS_OFF); 459 460 if (!(stats & CONC_STATUS_PENDING)) { /* No interrupt pending */ 461 mutex_exit(&dev->mutex); 462 return (DDI_INTR_UNCLAIMED); 463 } 464 465 do_dac = do_adc = NULL; 466 467 /* DAC1 (synth) interrupt */ 468 if (stats & CONC_STATUS_DAC1INT) { 469 470 ackbits |= CONC_SERCTL_DAC1IE; 471 port = &dev->port[PORT_DAC]; 472 if (port->trigger) { 473 do_dac = port->engine; 474 } 475 } 476 477 /* DAC2 interrupt */ 478 if (stats & CONC_STATUS_DAC2INT) { 479 480 ackbits |= CONC_SERCTL_DAC2IE; 481 } 482 483 /* ADC interrupt */ 484 if (stats & CONC_STATUS_ADCINT) { 485 486 ackbits |= CONC_SERCTL_ADCIE; 487 port = &dev->port[PORT_ADC]; 488 489 if (port->trigger) { 490 do_adc = port->engine; 491 } 492 } 493 494 /* UART interrupt - we shouldn't get this! */ 495 if (stats & CONC_STATUS_UARTINT) { 496 uint8_t uart_stat = GET8(dev, CONC_bUARTCSTAT_OFF); 497 while (uart_stat & CONC_UART_RXRDY) 498 uart_stat = GET8(dev, CONC_bUARTCSTAT_OFF); 499 } 500 501 /* Ack the interrupt */ 502 tmp = GET8(dev, CONC_bSERCTL_OFF); 503 PUT8(dev, CONC_bSERCTL_OFF, tmp & (~ackbits)); /* Clear bits */ 504 PUT8(dev, CONC_bSERCTL_OFF, tmp | ackbits); /* Turn them back on */ 505 506 if (dev->ksp) { 507 if (ackbits == 0) { 508 KSINTR(dev)->intrs[KSTAT_INTR_SPURIOUS]++; 509 } else { 510 KSINTR(dev)->intrs[KSTAT_INTR_HARD]++; 511 } 512 } 513 514 mutex_exit(&dev->mutex); 515 516 if (do_dac) 517 audio_engine_consume(do_dac); 518 if (do_adc) 519 audio_engine_produce(do_adc); 520 521 return (DDI_INTR_CLAIMED); 522 } 523 524 /* 525 * Audio routines 526 */ 527 static int 528 audioens_format(void *arg) 529 { 530 _NOTE(ARGUNUSED(arg)); 531 532 /* hardware can also do AUDIO_FORMAT_U8, but no need for it */ 533 return (AUDIO_FORMAT_S16_LE); 534 } 535 536 static int 537 audioens_channels(void *arg) 538 { 539 audioens_port_t *port = arg; 540 541 return (port->nchan); 542 } 543 544 static int 545 audioens_rate(void *arg) 546 { 547 audioens_port_t *port = arg; 548 549 return (port->speed); 550 } 551 552 static void 553 audioens_init_port(audioens_port_t *port) 554 { 555 audioens_dev_t *dev = port->dev; 556 unsigned tmp; 557 558 if (port->suspended) 559 return; 560 561 switch (port->num) { 562 case PORT_DAC: 563 /* Set physical address of the DMA buffer */ 564 audioens_writemem(dev, CONC_DAC1CTL_PAGE, CONC_dDAC1PADDR_OFF, 565 port->paddr); 566 audioens_writemem(dev, CONC_DAC2CTL_PAGE, CONC_dDAC2PADDR_OFF, 567 port->paddr + (port->nframes * sizeof (int16_t) * 2)); 568 569 /* Set DAC rate */ 570 SRCSetRate(dev, SRC_DAC1_BASE, port->speed); 571 SRCSetRate(dev, SRC_DAC2_BASE, port->speed); 572 573 /* Configure the channel setup - SPDIF only uses front */ 574 tmp = GET32(dev, CONC_dSTATUS_OFF); 575 tmp &= ~(CONC_STATUS_SPKR_MASK | CONC_STATUS_SPDIF_MASK); 576 tmp |= CONC_STATUS_SPKR_4CH | CONC_STATUS_SPDIF_P1; 577 PUT32(dev, CONC_dSTATUS_OFF, tmp); 578 579 /* Set format */ 580 PUT8(dev, CONC_bSKIPC_OFF, 0x10); 581 SET8(dev, CONC_bSERFMT_OFF, 582 CONC_PCM_DAC1_16BIT | CONC_PCM_DAC2_16BIT | 583 CONC_PCM_DAC1_STEREO | CONC_PCM_DAC2_STEREO); 584 585 /* Set the frame count */ 586 audioens_writemem(dev, CONC_DAC1CTL_PAGE, CONC_wDAC1FC_OFF, 587 port->nframes - 1); 588 audioens_writemem(dev, CONC_DAC2CTL_PAGE, CONC_wDAC2FC_OFF, 589 port->nframes - 1); 590 591 /* Set # of frames between interrupts */ 592 PUT16(dev, CONC_wDAC1IC_OFF, port->fragfr - 1); 593 PUT16(dev, CONC_wDAC2IC_OFF, port->fragfr - 1); 594 break; 595 596 case PORT_ADC: 597 /* Set physical address of the DMA buffer */ 598 audioens_writemem(dev, CONC_ADCCTL_PAGE, CONC_dADCPADDR_OFF, 599 port->paddr); 600 601 /* Set ADC rate */ 602 SRCSetRate(dev, SRC_ADC_BASE, port->speed); 603 604 /* Set format - for input we only support 16 bit input */ 605 tmp = GET8(dev, CONC_bSERFMT_OFF); 606 tmp |= CONC_PCM_ADC_16BIT; 607 tmp |= CONC_PCM_ADC_STEREO; 608 609 PUT8(dev, CONC_bSKIPC_OFF, 0x10); 610 611 PUT8(dev, CONC_bSERFMT_OFF, tmp); 612 613 /* Set the frame count */ 614 audioens_writemem(dev, CONC_ADCCTL_PAGE, CONC_wADCFC_OFF, 615 port->nframes - 1); 616 617 /* Set # of frames between interrupts */ 618 PUT16(dev, CONC_wADCIC_OFF, port->fragfr - 1); 619 620 break; 621 } 622 623 port->frameno = 0; 624 } 625 626 static int 627 audioens_open(void *arg, int flag, unsigned *fragfrp, unsigned *nfragsp, 628 caddr_t *bufp) 629 { 630 audioens_port_t *port = arg; 631 audioens_dev_t *dev = port->dev; 632 int intrs; 633 634 _NOTE(ARGUNUSED(flag)); 635 636 mutex_enter(&dev->mutex); 637 638 if (port->num == PORT_ADC) { 639 intrs = dev->rintrs; 640 } else { 641 intrs = dev->pintrs; 642 } 643 644 /* interrupt at least at 25 Hz, and not more than 250 Hz */ 645 intrs = min(250, max(25, intrs)); 646 647 port->fragfr = (port->speed / intrs); 648 port->nfrags = AUDIOENS_BUF_LEN / 649 (port->fragfr * port->nchan * sizeof (int16_t)); 650 port->nfrags = max(4, min(port->nfrags, 1024)); 651 port->nframes = port->nfrags * port->fragfr; 652 port->trigger = B_FALSE; 653 port->count = 0; 654 655 audioens_init_port(port); 656 657 *fragfrp = port->fragfr; 658 *nfragsp = port->nfrags; 659 *bufp = port->kaddr; 660 mutex_exit(&dev->mutex); 661 662 return (0); 663 } 664 665 static void 666 audioens_start_port(audioens_port_t *port) 667 { 668 audioens_dev_t *dev = port->dev; 669 670 if (!port->suspended) { 671 switch (port->num) { 672 case PORT_DAC: 673 SET8(dev, CONC_bDEVCTL_OFF, 674 CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_DAC1_EN); 675 SET8(dev, CONC_bSERCTL_OFF, CONC_SERCTL_DAC1IE); 676 break; 677 case PORT_ADC: 678 SET8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_ADC_EN); 679 SET8(dev, CONC_bSERCTL_OFF, CONC_SERCTL_ADCIE); 680 break; 681 } 682 } 683 } 684 685 static void 686 audioens_stop_port(audioens_port_t *port) 687 { 688 audioens_dev_t *dev = port->dev; 689 690 if (!port->suspended) { 691 switch (port->num) { 692 case PORT_DAC: 693 CLR8(dev, CONC_bDEVCTL_OFF, 694 CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_DAC1_EN); 695 CLR8(dev, CONC_bSERCTL_OFF, CONC_SERCTL_DAC1IE); 696 break; 697 case PORT_ADC: 698 CLR8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_ADC_EN); 699 CLR8(dev, CONC_bSERCTL_OFF, CONC_SERCTL_ADCIE); 700 break; 701 } 702 } 703 } 704 705 static int 706 audioens_start(void *arg) 707 { 708 audioens_port_t *port = arg; 709 audioens_dev_t *dev = port->dev; 710 711 mutex_enter(&dev->mutex); 712 if (!port->trigger) { 713 port->trigger = B_TRUE; 714 audioens_start_port(port); 715 } 716 mutex_exit(&dev->mutex); 717 718 return (0); 719 } 720 721 static void 722 audioens_stop(void *arg) 723 { 724 audioens_port_t *port = arg; 725 audioens_dev_t *dev = port->dev; 726 727 mutex_enter(&dev->mutex); 728 if (port->trigger) { 729 port->trigger = B_FALSE; 730 audioens_stop_port(port); 731 } 732 mutex_exit(&dev->mutex); 733 } 734 735 static void 736 audioens_update_port(audioens_port_t *port) 737 { 738 uint32_t page, offs; 739 int frameno, n; 740 741 switch (port->num) { 742 case PORT_DAC: 743 page = CONC_DAC1CTL_PAGE; 744 offs = CONC_wDAC1FC_OFF; 745 break; 746 747 case PORT_ADC: 748 page = CONC_ADCCTL_PAGE; 749 offs = CONC_wADCFC_OFF; 750 break; 751 } 752 753 /* 754 * Note that the current frame counter is in the high nybble. 755 */ 756 frameno = audioens_readmem(port->dev, page, offs) >> 16; 757 n = frameno >= port->frameno ? 758 frameno - port->frameno : 759 frameno + port->nframes - port->frameno; 760 port->frameno = frameno; 761 port->count += n; 762 } 763 764 static uint64_t 765 audioens_count(void *arg) 766 { 767 audioens_port_t *port = arg; 768 audioens_dev_t *dev = port->dev; 769 uint64_t val; 770 771 mutex_enter(&dev->mutex); 772 if (!port->suspended) { 773 audioens_update_port(port); 774 } 775 val = port->count; 776 mutex_exit(&dev->mutex); 777 return (val); 778 } 779 780 static void 781 audioens_close(void *arg) 782 { 783 audioens_port_t *port = arg; 784 785 audioens_stop(port); 786 } 787 788 static void 789 audioens_sync(void *arg, unsigned nframes) 790 { 791 audioens_port_t *port = arg; 792 793 _NOTE(ARGUNUSED(nframes)); 794 795 if (port->num == PORT_ADC) { 796 (void) ddi_dma_sync(port->dmah, 0, 0, DDI_DMA_SYNC_FORCPU); 797 } else { 798 (void) ddi_dma_sync(port->dmah, 0, 0, DDI_DMA_SYNC_FORDEV); 799 } 800 } 801 802 static size_t 803 audioens_qlen(void *arg) 804 { 805 audioens_port_t *port = arg; 806 807 return (port->fragfr); 808 } 809 810 static void 811 audioens_chinfo(void *arg, int chan, unsigned *offset, unsigned *incr) 812 { 813 audioens_port_t *port = arg; 814 815 if ((port->num == PORT_DAC) && (chan >= 2)) { 816 *offset = (port->nframes * 2) + (chan % 2); 817 *incr = 2; 818 } else { 819 *offset = chan; 820 *incr = 2; 821 } 822 } 823 824 audio_engine_ops_t audioens_engine_ops = { 825 AUDIO_ENGINE_VERSION, /* version number */ 826 audioens_open, 827 audioens_close, 828 audioens_start, 829 audioens_stop, 830 audioens_count, 831 audioens_format, 832 audioens_channels, 833 audioens_rate, 834 audioens_sync, 835 audioens_qlen, 836 audioens_chinfo 837 }; 838 839 void 840 audioens_init_hw(audioens_dev_t *dev) 841 { 842 int tmp; 843 844 if ((dev->devid == ENSONIQ_ES5880) || 845 (dev->devid == ENSONIQ_ES5880A) || 846 (dev->devid == ENSONIQ_ES5880B) || 847 (dev->devid == 0x1371 && dev->revision == 7) || 848 (dev->devid == 0x1371 && dev->revision >= 9)) { 849 850 /* Have a ES5880 so enable the codec manually */ 851 tmp = GET8(dev, CONC_bINTSUMM_OFF) & 0xff; 852 tmp |= 0x20; 853 PUT8(dev, CONC_bINTSUMM_OFF, tmp); 854 for (int i = 0; i < 2000; i++) 855 drv_usecwait(10); 856 } 857 858 SRCInit(dev); 859 860 #if 0 861 PUT8(dev, CONC_bSERCTL_OFF, 0x00); 862 PUT8(dev, CONC_bNMIENA_OFF, 0x00); /* NMI off */ 863 PUT8(dev, CONC_wNMISTAT_OFF, 0x00); /* PUT8? */ 864 #endif 865 866 /* 867 * Turn on CODEC (UART and joystick left disabled) 868 */ 869 tmp = GET32(dev, CONC_bDEVCTL_OFF) & 0xff; 870 tmp &= ~(CONC_DEVCTL_PCICLK_DS | CONC_DEVCTL_XTALCLK_DS); 871 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 872 PUT8(dev, CONC_bUARTCSTAT_OFF, 0x00); 873 874 /* Perform AC97 codec warm reset */ 875 tmp = GET8(dev, CONC_bMISCCTL_OFF) & 0xff; 876 PUT8(dev, CONC_bMISCCTL_OFF, tmp | CONC_MISCCTL_SYNC_RES); 877 drv_usecwait(200); 878 PUT8(dev, CONC_bMISCCTL_OFF, tmp); 879 drv_usecwait(200); 880 881 if (dev->revision >= 4) { 882 /* XXX: enable SPDIF - PCM only for now */ 883 if (audioens_spdif) { 884 /* enable SPDIF */ 885 PUT32(dev, 0x04, GET32(dev, 0x04) | (1 << 18)); 886 /* SPDIF out = data from DAC */ 887 PUT32(dev, 0x00, GET32(dev, 0x00) | (1 << 26)); 888 CLR32(dev, CONC_dSPDIF_OFF, CONC_SPDIF_AC3); 889 890 } else { 891 /* disable spdif out */ 892 PUT32(dev, 0x04, GET32(dev, 0x04) & ~(1 << 18)); 893 PUT32(dev, 0x00, GET32(dev, 0x00) & ~(1 << 26)); 894 } 895 896 /* we want to run each channel independently */ 897 CLR32(dev, CONC_dSTATUS_OFF, CONC_STATUS_ECHO); 898 } 899 900 dev->enabled = B_TRUE; 901 } 902 903 static int 904 audioens_init(audioens_dev_t *dev) 905 { 906 907 audioens_init_hw(dev); 908 909 /* 910 * On this hardware, we want to disable the internal speaker by 911 * default, if it exists. (We don't have a speakerphone on any 912 * of these cards, and no SPARC hardware uses it either!) 913 */ 914 ddi_prop_update_int(DDI_DEV_T_NONE, dev->dip, AC97_PROP_SPEAKER, 0); 915 916 /* 917 * Init mixer 918 */ 919 920 dev->ac97 = ac97_alloc(dev->dip, audioens_rd97, audioens_wr97, dev); 921 if (dev->ac97 == NULL) 922 return (DDI_FAILURE); 923 924 if (ac97_init(dev->ac97, dev->osdev) != 0) { 925 return (DDI_FAILURE); 926 } 927 928 dev->pintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip, 929 DDI_PROP_DONTPASS, "play-interrupts", DEFINTS); 930 931 dev->rintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip, 932 DDI_PROP_DONTPASS, "record-interrupts", DEFINTS); 933 934 for (int i = 0; i <= PORT_MAX; i++) { 935 audioens_port_t *port; 936 unsigned caps; 937 unsigned dmaflags; 938 size_t rlen; 939 ddi_dma_cookie_t c; 940 unsigned ccnt; 941 942 port = &dev->port[i]; 943 port->dev = dev; 944 945 switch (i) { 946 case PORT_DAC: 947 port->nchan = 4; 948 port->speed = 48000; 949 caps = ENGINE_OUTPUT_CAP; 950 dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT; 951 break; 952 953 case PORT_ADC: 954 port->nchan = 2; 955 port->speed = 48000; 956 caps = ENGINE_INPUT_CAP; 957 dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT; 958 break; 959 } 960 961 port->num = i; 962 963 /* 964 * Allocate DMA resources. 965 */ 966 967 if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_SLEEP, 968 NULL, &port->dmah) != DDI_SUCCESS) { 969 audio_dev_warn(dev->osdev, 970 "port %d: dma handle allocation failed", i); 971 return (DDI_FAILURE); 972 } 973 if (ddi_dma_mem_alloc(port->dmah, AUDIOENS_BUF_LEN, &buf_attr, 974 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &port->kaddr, 975 &rlen, &port->acch) != DDI_SUCCESS) { 976 audio_dev_warn(dev->osdev, 977 "port %d: dma memory allocation failed", i); 978 return (DDI_FAILURE); 979 } 980 /* ensure that the buffer is zeroed out properly */ 981 bzero(port->kaddr, rlen); 982 if (ddi_dma_addr_bind_handle(port->dmah, NULL, port->kaddr, 983 AUDIOENS_BUF_LEN, dmaflags, DDI_DMA_SLEEP, NULL, 984 &c, &ccnt) != DDI_DMA_MAPPED) { 985 audio_dev_warn(dev->osdev, 986 "port %d: dma binding failed", i); 987 return (DDI_FAILURE); 988 } 989 port->paddr = c.dmac_address; 990 991 /* 992 * Allocate and configure audio engine. 993 */ 994 port->engine = audio_engine_alloc(&audioens_engine_ops, caps); 995 if (port->engine == NULL) { 996 audio_dev_warn(dev->osdev, 997 "port %d: audio_engine_alloc failed", i); 998 return (DDI_FAILURE); 999 } 1000 1001 audio_engine_set_private(port->engine, port); 1002 audio_dev_add_engine(dev->osdev, port->engine); 1003 } 1004 1005 /* 1006 * Set up kstats for interrupt reporting. 1007 */ 1008 dev->ksp = kstat_create(ddi_driver_name(dev->dip), 1009 ddi_get_instance(dev->dip), ddi_driver_name(dev->dip), 1010 "controller", KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT); 1011 if (dev->ksp != NULL) { 1012 kstat_install(dev->ksp); 1013 } 1014 1015 if (audio_dev_register(dev->osdev) != DDI_SUCCESS) { 1016 audio_dev_warn(dev->osdev, 1017 "unable to register with audio framework"); 1018 return (DDI_FAILURE); 1019 } 1020 1021 return (DDI_SUCCESS); 1022 } 1023 1024 int 1025 audioens_setup_interrupts(audioens_dev_t *dev) 1026 { 1027 int actual; 1028 uint_t ipri; 1029 1030 if ((ddi_intr_alloc(dev->dip, dev->ihandle, DDI_INTR_TYPE_FIXED, 1031 0, 1, &actual, DDI_INTR_ALLOC_NORMAL) != DDI_SUCCESS) || 1032 (actual != 1)) { 1033 audio_dev_warn(dev->osdev, "can't alloc intr handle"); 1034 return (DDI_FAILURE); 1035 } 1036 1037 if (ddi_intr_get_pri(dev->ihandle[0], &ipri) != DDI_SUCCESS) { 1038 audio_dev_warn(dev->osdev, "can't determine intr priority"); 1039 (void) ddi_intr_free(dev->ihandle[0]); 1040 dev->ihandle[0] = NULL; 1041 return (DDI_FAILURE); 1042 } 1043 1044 if (ddi_intr_add_handler(dev->ihandle[0], audioens_intr, dev, 1045 NULL) != DDI_SUCCESS) { 1046 audio_dev_warn(dev->osdev, "can't add intr handler"); 1047 (void) ddi_intr_free(dev->ihandle[0]); 1048 dev->ihandle[0] = NULL; 1049 return (DDI_FAILURE); 1050 } 1051 1052 mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, DDI_INTR_PRI(ipri)); 1053 1054 return (DDI_SUCCESS); 1055 } 1056 1057 void 1058 audioens_destroy(audioens_dev_t *dev) 1059 { 1060 int i; 1061 1062 if (dev->ihandle[0] != NULL) { 1063 (void) ddi_intr_disable(dev->ihandle[0]); 1064 (void) ddi_intr_remove_handler(dev->ihandle[0]); 1065 (void) ddi_intr_free(dev->ihandle[0]); 1066 mutex_destroy(&dev->mutex); 1067 } 1068 1069 if (dev->ksp != NULL) { 1070 kstat_delete(dev->ksp); 1071 } 1072 1073 /* free up ports, including DMA resources for ports */ 1074 for (i = 0; i <= PORT_MAX; i++) { 1075 audioens_port_t *port = &dev->port[i]; 1076 1077 if (port->paddr != 0) 1078 (void) ddi_dma_unbind_handle(port->dmah); 1079 if (port->acch != NULL) 1080 ddi_dma_mem_free(&port->acch); 1081 if (port->dmah != NULL) 1082 ddi_dma_free_handle(&port->dmah); 1083 1084 if (port->engine != NULL) { 1085 audio_dev_remove_engine(dev->osdev, port->engine); 1086 audio_engine_free(port->engine); 1087 } 1088 } 1089 1090 if (dev->acch != NULL) { 1091 ddi_regs_map_free(&dev->acch); 1092 } 1093 1094 if (dev->ac97) { 1095 ac97_free(dev->ac97); 1096 } 1097 1098 if (dev->osdev != NULL) { 1099 audio_dev_free(dev->osdev); 1100 } 1101 1102 kmem_free(dev, sizeof (*dev)); 1103 } 1104 1105 int 1106 audioens_attach(dev_info_t *dip) 1107 { 1108 uint16_t pci_command, vendor, device; 1109 uint8_t revision; 1110 audioens_dev_t *dev; 1111 ddi_acc_handle_t pcih; 1112 const char *chip_name; 1113 const char *chip_vers; 1114 1115 dev = kmem_zalloc(sizeof (*dev), KM_SLEEP); 1116 dev->dip = dip; 1117 ddi_set_driver_private(dip, dev); 1118 1119 if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) { 1120 audio_dev_warn(dev->osdev, "pci_config_setup failed"); 1121 kmem_free(dev, sizeof (*dev)); 1122 return (DDI_FAILURE); 1123 } 1124 1125 vendor = pci_config_get16(pcih, PCI_CONF_VENID); 1126 device = pci_config_get16(pcih, PCI_CONF_DEVID); 1127 revision = pci_config_get8(pcih, PCI_CONF_REVID); 1128 1129 if ((vendor != ENSONIQ_VENDOR_ID && vendor != CREATIVE_VENDOR_ID) || 1130 (device != ENSONIQ_ES1371 && device != ENSONIQ_ES5880 && 1131 device != ENSONIQ_ES5880A && device != ECTIVA_ES1938 && 1132 device != ENSONIQ_ES5880B)) 1133 goto err_exit; 1134 1135 chip_name = "AudioPCI97"; 1136 chip_vers = "unknown"; 1137 1138 switch (device) { 1139 case ENSONIQ_ES1371: 1140 chip_name = "AudioPCI97"; 1141 switch (revision) { 1142 case 0x02: 1143 case 0x09: 1144 default: 1145 chip_vers = "ES1371"; 1146 break; 1147 case 0x04: 1148 case 0x06: 1149 case 0x08: 1150 chip_vers = "ES1373"; 1151 break; 1152 case 0x07: 1153 chip_vers = "ES5880"; 1154 break; 1155 } 1156 break; 1157 1158 case ENSONIQ_ES5880: 1159 chip_name = "SB PCI128"; 1160 chip_vers = "ES5880"; 1161 break; 1162 case ENSONIQ_ES5880A: 1163 chip_name = "SB PCI128"; 1164 chip_vers = "ES5880A"; 1165 break; 1166 case ENSONIQ_ES5880B: 1167 chip_name = "SB PCI128"; 1168 chip_vers = "ES5880B"; 1169 break; 1170 1171 case ECTIVA_ES1938: 1172 chip_name = "AudioPCI"; 1173 chip_vers = "ES1938"; 1174 break; 1175 } 1176 1177 dev->revision = revision; 1178 dev->devid = device; 1179 1180 dev->osdev = audio_dev_alloc(dip, 0); 1181 if (dev->osdev == NULL) { 1182 goto err_exit; 1183 } 1184 1185 audio_dev_set_description(dev->osdev, chip_name); 1186 audio_dev_set_version(dev->osdev, chip_vers); 1187 1188 /* set the PCI latency */ 1189 if ((audioens_latency == 32) || (audioens_latency == 64) || 1190 (audioens_latency == 96)) 1191 pci_config_put8(pcih, PCI_CONF_LATENCY_TIMER, 1192 audioens_latency); 1193 1194 /* activate the device */ 1195 pci_command = pci_config_get16(pcih, PCI_CONF_COMM); 1196 pci_command |= PCI_COMM_ME | PCI_COMM_IO; 1197 pci_config_put16(pcih, PCI_CONF_COMM, pci_command); 1198 1199 /* map registers */ 1200 if (ddi_regs_map_setup(dip, 1, &dev->regs, 0, 0, &acc_attr, 1201 &dev->acch) != DDI_SUCCESS) { 1202 audio_dev_warn(dev->osdev, "can't map registers"); 1203 goto err_exit; 1204 } 1205 1206 if (audioens_setup_interrupts(dev) != DDI_SUCCESS) { 1207 audio_dev_warn(dev->osdev, "can't register interrupts"); 1208 goto err_exit; 1209 } 1210 1211 /* This allocates and configures the engines */ 1212 if (audioens_init(dev) != DDI_SUCCESS) { 1213 audio_dev_warn(dev->osdev, "can't init device"); 1214 goto err_exit; 1215 } 1216 1217 (void) ddi_intr_enable(dev->ihandle[0]); 1218 1219 pci_config_teardown(&pcih); 1220 1221 ddi_report_dev(dip); 1222 1223 return (DDI_SUCCESS); 1224 1225 err_exit: 1226 pci_config_teardown(&pcih); 1227 1228 audioens_destroy(dev); 1229 1230 return (DDI_FAILURE); 1231 } 1232 1233 int 1234 audioens_detach(audioens_dev_t *dev) 1235 { 1236 int tmp; 1237 1238 /* first unregister us from the DDI framework, might be busy */ 1239 if (audio_dev_unregister(dev->osdev) != DDI_SUCCESS) 1240 return (DDI_FAILURE); 1241 1242 mutex_enter(&dev->mutex); 1243 1244 tmp = GET8(dev, CONC_bSERCTL_OFF) & 1245 ~(CONC_SERCTL_DAC2IE | CONC_SERCTL_DAC1IE | CONC_SERCTL_ADCIE); 1246 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1247 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1248 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1249 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1250 1251 tmp = GET8(dev, CONC_bDEVCTL_OFF) & 1252 ~(CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_DAC1_EN); 1253 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1254 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1255 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1256 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1257 1258 dev->enabled = B_FALSE; 1259 1260 mutex_exit(&dev->mutex); 1261 1262 audioens_destroy(dev); 1263 1264 return (DDI_SUCCESS); 1265 } 1266 1267 /*ARGSUSED*/ 1268 static int 1269 audioens_resume(audioens_dev_t *dev) 1270 { 1271 /* ask framework to reset/relocate engine data */ 1272 for (int i = 0; i <= PORT_MAX; i++) { 1273 audio_engine_reset(dev->port[i].engine); 1274 } 1275 1276 /* reinitialize hardware */ 1277 audioens_init_hw(dev); 1278 1279 /* restore AC97 state */ 1280 ac97_resume(dev->ac97); 1281 1282 /* restart ports */ 1283 mutex_enter(&dev->mutex); 1284 for (int i = 0; i < PORT_MAX; i++) { 1285 audioens_port_t *port = &dev->port[i]; 1286 port->suspended = B_FALSE; 1287 audioens_init_port(port); 1288 /* possibly start it up if was going when we suspended */ 1289 if (port->trigger) { 1290 audioens_start_port(port); 1291 1292 } 1293 } 1294 mutex_exit(&dev->mutex); 1295 for (int i = 0; i < PORT_MAX; i++) { 1296 audioens_port_t *port = &dev->port[i]; 1297 /* signal callbacks on resume */ 1298 if (!port->trigger) 1299 continue; 1300 if (port->num == PORT_ADC) { 1301 audio_engine_produce(port->engine); 1302 } else { 1303 audio_engine_consume(port->engine); 1304 } 1305 } 1306 return (DDI_SUCCESS); 1307 } 1308 1309 /*ARGSUSED*/ 1310 static int 1311 audioens_suspend(audioens_dev_t *dev) 1312 { 1313 /* 1314 * Stop all engines/DMA data. 1315 */ 1316 mutex_enter(&dev->mutex); 1317 for (int i = 0; i <= PORT_MAX; i++) { 1318 audioens_stop_port(&dev->port[i]); 1319 audioens_update_port(&dev->port[i]); 1320 dev->port[i].suspended = B_TRUE; 1321 } 1322 dev->enabled = B_FALSE; 1323 mutex_exit(&dev->mutex); 1324 1325 /* 1326 * Framework needs to save off AC'97 state. 1327 */ 1328 ac97_suspend(dev->ac97); 1329 1330 return (DDI_SUCCESS); 1331 } 1332 1333 static int 1334 audioens_quiesce(dev_info_t *dip) 1335 { 1336 audioens_dev_t *dev; 1337 uint8_t tmp; 1338 1339 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1340 return (DDI_FAILURE); 1341 } 1342 1343 /* This disables all DMA engines and interrupts */ 1344 tmp = GET8(dev, CONC_bSERCTL_OFF) & 1345 ~(CONC_SERCTL_DAC2IE | CONC_SERCTL_DAC1IE | CONC_SERCTL_ADCIE); 1346 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1347 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1348 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1349 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1350 1351 tmp = GET8(dev, CONC_bDEVCTL_OFF) & 1352 ~(CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_DAC1_EN); 1353 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1354 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1355 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1356 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1357 1358 return (DDI_SUCCESS); 1359 } 1360 1361 1362 static int 1363 audioens_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1364 { 1365 audioens_dev_t *dev; 1366 1367 switch (cmd) { 1368 case DDI_ATTACH: 1369 return (audioens_attach(dip)); 1370 1371 case DDI_RESUME: 1372 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1373 return (DDI_FAILURE); 1374 } 1375 return (audioens_resume(dev)); 1376 1377 default: 1378 return (DDI_FAILURE); 1379 } 1380 } 1381 1382 static int 1383 audioens_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1384 { 1385 audioens_dev_t *dev; 1386 1387 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1388 return (DDI_FAILURE); 1389 } 1390 1391 switch (cmd) { 1392 case DDI_DETACH: 1393 return (audioens_detach(dev)); 1394 1395 case DDI_SUSPEND: 1396 return (audioens_suspend(dev)); 1397 default: 1398 return (DDI_FAILURE); 1399 } 1400 } 1401 1402 static int audioens_ddi_attach(dev_info_t *, ddi_attach_cmd_t); 1403 static int audioens_ddi_detach(dev_info_t *, ddi_detach_cmd_t); 1404 1405 static struct dev_ops audioens_dev_ops = { 1406 DEVO_REV, /* rev */ 1407 0, /* refcnt */ 1408 NULL, /* getinfo */ 1409 nulldev, /* identify */ 1410 nulldev, /* probe */ 1411 audioens_ddi_attach, /* attach */ 1412 audioens_ddi_detach, /* detach */ 1413 nodev, /* reset */ 1414 NULL, /* cb_ops */ 1415 NULL, /* bus_ops */ 1416 NULL, /* power */ 1417 audioens_quiesce, /* quiesce */ 1418 }; 1419 1420 static struct modldrv audioens_modldrv = { 1421 &mod_driverops, /* drv_modops */ 1422 "Ensoniq 1371/1373 Audio", /* linkinfo */ 1423 &audioens_dev_ops, /* dev_ops */ 1424 }; 1425 1426 static struct modlinkage modlinkage = { 1427 MODREV_1, 1428 { &audioens_modldrv, NULL } 1429 }; 1430 1431 int 1432 _init(void) 1433 { 1434 int rv; 1435 1436 audio_init_ops(&audioens_dev_ops, DRVNAME); 1437 if ((rv = mod_install(&modlinkage)) != 0) { 1438 audio_fini_ops(&audioens_dev_ops); 1439 } 1440 return (rv); 1441 } 1442 1443 int 1444 _fini(void) 1445 { 1446 int rv; 1447 1448 if ((rv = mod_remove(&modlinkage)) == 0) { 1449 audio_fini_ops(&audioens_dev_ops); 1450 } 1451 return (rv); 1452 } 1453 1454 int 1455 _info(struct modinfo *modinfop) 1456 { 1457 return (mod_info(&modlinkage, modinfop)); 1458 } 1459