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 (void) ddi_prop_update_int(DDI_DEV_T_NONE, dev->dip, AC97_PROP_SPEAKER, 915 0); 916 917 /* 918 * Init mixer 919 */ 920 921 dev->ac97 = ac97_alloc(dev->dip, audioens_rd97, audioens_wr97, dev); 922 if (dev->ac97 == NULL) 923 return (DDI_FAILURE); 924 925 if (ac97_init(dev->ac97, dev->osdev) != 0) { 926 return (DDI_FAILURE); 927 } 928 929 dev->pintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip, 930 DDI_PROP_DONTPASS, "play-interrupts", DEFINTS); 931 932 dev->rintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip, 933 DDI_PROP_DONTPASS, "record-interrupts", DEFINTS); 934 935 for (int i = 0; i <= PORT_MAX; i++) { 936 audioens_port_t *port; 937 unsigned caps; 938 unsigned dmaflags; 939 size_t rlen; 940 ddi_dma_cookie_t c; 941 unsigned ccnt; 942 943 port = &dev->port[i]; 944 port->dev = dev; 945 946 switch (i) { 947 case PORT_DAC: 948 port->nchan = 4; 949 port->speed = 48000; 950 caps = ENGINE_OUTPUT_CAP; 951 dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT; 952 break; 953 954 case PORT_ADC: 955 port->nchan = 2; 956 port->speed = 48000; 957 caps = ENGINE_INPUT_CAP; 958 dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT; 959 break; 960 } 961 962 port->num = i; 963 964 /* 965 * Allocate DMA resources. 966 */ 967 968 if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_SLEEP, 969 NULL, &port->dmah) != DDI_SUCCESS) { 970 audio_dev_warn(dev->osdev, 971 "port %d: dma handle allocation failed", i); 972 return (DDI_FAILURE); 973 } 974 if (ddi_dma_mem_alloc(port->dmah, AUDIOENS_BUF_LEN, &buf_attr, 975 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &port->kaddr, 976 &rlen, &port->acch) != DDI_SUCCESS) { 977 audio_dev_warn(dev->osdev, 978 "port %d: dma memory allocation failed", i); 979 return (DDI_FAILURE); 980 } 981 /* ensure that the buffer is zeroed out properly */ 982 bzero(port->kaddr, rlen); 983 if (ddi_dma_addr_bind_handle(port->dmah, NULL, port->kaddr, 984 AUDIOENS_BUF_LEN, dmaflags, DDI_DMA_SLEEP, NULL, 985 &c, &ccnt) != DDI_DMA_MAPPED) { 986 audio_dev_warn(dev->osdev, 987 "port %d: dma binding failed", i); 988 return (DDI_FAILURE); 989 } 990 port->paddr = c.dmac_address; 991 992 /* 993 * Allocate and configure audio engine. 994 */ 995 port->engine = audio_engine_alloc(&audioens_engine_ops, caps); 996 if (port->engine == NULL) { 997 audio_dev_warn(dev->osdev, 998 "port %d: audio_engine_alloc failed", i); 999 return (DDI_FAILURE); 1000 } 1001 1002 audio_engine_set_private(port->engine, port); 1003 audio_dev_add_engine(dev->osdev, port->engine); 1004 } 1005 1006 /* 1007 * Set up kstats for interrupt reporting. 1008 */ 1009 dev->ksp = kstat_create(ddi_driver_name(dev->dip), 1010 ddi_get_instance(dev->dip), ddi_driver_name(dev->dip), 1011 "controller", KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT); 1012 if (dev->ksp != NULL) { 1013 kstat_install(dev->ksp); 1014 } 1015 1016 if (audio_dev_register(dev->osdev) != DDI_SUCCESS) { 1017 audio_dev_warn(dev->osdev, 1018 "unable to register with audio framework"); 1019 return (DDI_FAILURE); 1020 } 1021 1022 return (DDI_SUCCESS); 1023 } 1024 1025 int 1026 audioens_setup_interrupts(audioens_dev_t *dev) 1027 { 1028 int actual; 1029 uint_t ipri; 1030 1031 if ((ddi_intr_alloc(dev->dip, dev->ihandle, DDI_INTR_TYPE_FIXED, 1032 0, 1, &actual, DDI_INTR_ALLOC_NORMAL) != DDI_SUCCESS) || 1033 (actual != 1)) { 1034 audio_dev_warn(dev->osdev, "can't alloc intr handle"); 1035 return (DDI_FAILURE); 1036 } 1037 1038 if (ddi_intr_get_pri(dev->ihandle[0], &ipri) != DDI_SUCCESS) { 1039 audio_dev_warn(dev->osdev, "can't determine intr priority"); 1040 (void) ddi_intr_free(dev->ihandle[0]); 1041 dev->ihandle[0] = NULL; 1042 return (DDI_FAILURE); 1043 } 1044 1045 if (ddi_intr_add_handler(dev->ihandle[0], audioens_intr, dev, 1046 NULL) != DDI_SUCCESS) { 1047 audio_dev_warn(dev->osdev, "can't add intr handler"); 1048 (void) ddi_intr_free(dev->ihandle[0]); 1049 dev->ihandle[0] = NULL; 1050 return (DDI_FAILURE); 1051 } 1052 1053 mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, DDI_INTR_PRI(ipri)); 1054 1055 return (DDI_SUCCESS); 1056 } 1057 1058 void 1059 audioens_destroy(audioens_dev_t *dev) 1060 { 1061 int i; 1062 1063 if (dev->ihandle[0] != NULL) { 1064 (void) ddi_intr_disable(dev->ihandle[0]); 1065 (void) ddi_intr_remove_handler(dev->ihandle[0]); 1066 (void) ddi_intr_free(dev->ihandle[0]); 1067 mutex_destroy(&dev->mutex); 1068 } 1069 1070 if (dev->ksp != NULL) { 1071 kstat_delete(dev->ksp); 1072 } 1073 1074 /* free up ports, including DMA resources for ports */ 1075 for (i = 0; i <= PORT_MAX; i++) { 1076 audioens_port_t *port = &dev->port[i]; 1077 1078 if (port->paddr != 0) 1079 (void) ddi_dma_unbind_handle(port->dmah); 1080 if (port->acch != NULL) 1081 ddi_dma_mem_free(&port->acch); 1082 if (port->dmah != NULL) 1083 ddi_dma_free_handle(&port->dmah); 1084 1085 if (port->engine != NULL) { 1086 audio_dev_remove_engine(dev->osdev, port->engine); 1087 audio_engine_free(port->engine); 1088 } 1089 } 1090 1091 if (dev->acch != NULL) { 1092 ddi_regs_map_free(&dev->acch); 1093 } 1094 1095 if (dev->ac97) { 1096 ac97_free(dev->ac97); 1097 } 1098 1099 if (dev->osdev != NULL) { 1100 audio_dev_free(dev->osdev); 1101 } 1102 1103 kmem_free(dev, sizeof (*dev)); 1104 } 1105 1106 int 1107 audioens_attach(dev_info_t *dip) 1108 { 1109 uint16_t pci_command, vendor, device; 1110 uint8_t revision; 1111 audioens_dev_t *dev; 1112 ddi_acc_handle_t pcih; 1113 const char *chip_name; 1114 const char *chip_vers; 1115 1116 dev = kmem_zalloc(sizeof (*dev), KM_SLEEP); 1117 dev->dip = dip; 1118 ddi_set_driver_private(dip, dev); 1119 1120 if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) { 1121 audio_dev_warn(dev->osdev, "pci_config_setup failed"); 1122 kmem_free(dev, sizeof (*dev)); 1123 return (DDI_FAILURE); 1124 } 1125 1126 vendor = pci_config_get16(pcih, PCI_CONF_VENID); 1127 device = pci_config_get16(pcih, PCI_CONF_DEVID); 1128 revision = pci_config_get8(pcih, PCI_CONF_REVID); 1129 1130 if ((vendor != ENSONIQ_VENDOR_ID && vendor != CREATIVE_VENDOR_ID) || 1131 (device != ENSONIQ_ES1371 && device != ENSONIQ_ES5880 && 1132 device != ENSONIQ_ES5880A && device != ECTIVA_ES1938 && 1133 device != ENSONIQ_ES5880B)) 1134 goto err_exit; 1135 1136 chip_name = "AudioPCI97"; 1137 chip_vers = "unknown"; 1138 1139 switch (device) { 1140 case ENSONIQ_ES1371: 1141 chip_name = "AudioPCI97"; 1142 switch (revision) { 1143 case 0x02: 1144 case 0x09: 1145 default: 1146 chip_vers = "ES1371"; 1147 break; 1148 case 0x04: 1149 case 0x06: 1150 case 0x08: 1151 chip_vers = "ES1373"; 1152 break; 1153 case 0x07: 1154 chip_vers = "ES5880"; 1155 break; 1156 } 1157 break; 1158 1159 case ENSONIQ_ES5880: 1160 chip_name = "SB PCI128"; 1161 chip_vers = "ES5880"; 1162 break; 1163 case ENSONIQ_ES5880A: 1164 chip_name = "SB PCI128"; 1165 chip_vers = "ES5880A"; 1166 break; 1167 case ENSONIQ_ES5880B: 1168 chip_name = "SB PCI128"; 1169 chip_vers = "ES5880B"; 1170 break; 1171 1172 case ECTIVA_ES1938: 1173 chip_name = "AudioPCI"; 1174 chip_vers = "ES1938"; 1175 break; 1176 } 1177 1178 dev->revision = revision; 1179 dev->devid = device; 1180 1181 dev->osdev = audio_dev_alloc(dip, 0); 1182 if (dev->osdev == NULL) { 1183 goto err_exit; 1184 } 1185 1186 audio_dev_set_description(dev->osdev, chip_name); 1187 audio_dev_set_version(dev->osdev, chip_vers); 1188 1189 /* set the PCI latency */ 1190 if ((audioens_latency == 32) || (audioens_latency == 64) || 1191 (audioens_latency == 96)) 1192 pci_config_put8(pcih, PCI_CONF_LATENCY_TIMER, 1193 audioens_latency); 1194 1195 /* activate the device */ 1196 pci_command = pci_config_get16(pcih, PCI_CONF_COMM); 1197 pci_command |= PCI_COMM_ME | PCI_COMM_IO; 1198 pci_config_put16(pcih, PCI_CONF_COMM, pci_command); 1199 1200 /* map registers */ 1201 if (ddi_regs_map_setup(dip, 1, &dev->regs, 0, 0, &acc_attr, 1202 &dev->acch) != DDI_SUCCESS) { 1203 audio_dev_warn(dev->osdev, "can't map registers"); 1204 goto err_exit; 1205 } 1206 1207 if (audioens_setup_interrupts(dev) != DDI_SUCCESS) { 1208 audio_dev_warn(dev->osdev, "can't register interrupts"); 1209 goto err_exit; 1210 } 1211 1212 /* This allocates and configures the engines */ 1213 if (audioens_init(dev) != DDI_SUCCESS) { 1214 audio_dev_warn(dev->osdev, "can't init device"); 1215 goto err_exit; 1216 } 1217 1218 (void) ddi_intr_enable(dev->ihandle[0]); 1219 1220 pci_config_teardown(&pcih); 1221 1222 ddi_report_dev(dip); 1223 1224 return (DDI_SUCCESS); 1225 1226 err_exit: 1227 pci_config_teardown(&pcih); 1228 1229 audioens_destroy(dev); 1230 1231 return (DDI_FAILURE); 1232 } 1233 1234 int 1235 audioens_detach(audioens_dev_t *dev) 1236 { 1237 int tmp; 1238 1239 /* first unregister us from the DDI framework, might be busy */ 1240 if (audio_dev_unregister(dev->osdev) != DDI_SUCCESS) 1241 return (DDI_FAILURE); 1242 1243 mutex_enter(&dev->mutex); 1244 1245 tmp = GET8(dev, CONC_bSERCTL_OFF) & 1246 ~(CONC_SERCTL_DAC2IE | CONC_SERCTL_DAC1IE | CONC_SERCTL_ADCIE); 1247 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1248 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1249 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1250 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1251 1252 tmp = GET8(dev, CONC_bDEVCTL_OFF) & 1253 ~(CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_DAC1_EN); 1254 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1255 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1256 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1257 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1258 1259 dev->enabled = B_FALSE; 1260 1261 mutex_exit(&dev->mutex); 1262 1263 audioens_destroy(dev); 1264 1265 return (DDI_SUCCESS); 1266 } 1267 1268 /*ARGSUSED*/ 1269 static int 1270 audioens_resume(audioens_dev_t *dev) 1271 { 1272 /* ask framework to reset/relocate engine data */ 1273 for (int i = 0; i <= PORT_MAX; i++) { 1274 audio_engine_reset(dev->port[i].engine); 1275 } 1276 1277 /* reinitialize hardware */ 1278 audioens_init_hw(dev); 1279 1280 /* restore AC97 state */ 1281 ac97_resume(dev->ac97); 1282 1283 /* restart ports */ 1284 mutex_enter(&dev->mutex); 1285 for (int i = 0; i < PORT_MAX; i++) { 1286 audioens_port_t *port = &dev->port[i]; 1287 port->suspended = B_FALSE; 1288 audioens_init_port(port); 1289 /* possibly start it up if was going when we suspended */ 1290 if (port->trigger) { 1291 audioens_start_port(port); 1292 1293 } 1294 } 1295 mutex_exit(&dev->mutex); 1296 for (int i = 0; i < PORT_MAX; i++) { 1297 audioens_port_t *port = &dev->port[i]; 1298 /* signal callbacks on resume */ 1299 if (!port->trigger) 1300 continue; 1301 if (port->num == PORT_ADC) { 1302 audio_engine_produce(port->engine); 1303 } else { 1304 audio_engine_consume(port->engine); 1305 } 1306 } 1307 return (DDI_SUCCESS); 1308 } 1309 1310 /*ARGSUSED*/ 1311 static int 1312 audioens_suspend(audioens_dev_t *dev) 1313 { 1314 /* 1315 * Stop all engines/DMA data. 1316 */ 1317 mutex_enter(&dev->mutex); 1318 for (int i = 0; i <= PORT_MAX; i++) { 1319 audioens_stop_port(&dev->port[i]); 1320 audioens_update_port(&dev->port[i]); 1321 dev->port[i].suspended = B_TRUE; 1322 } 1323 dev->enabled = B_FALSE; 1324 mutex_exit(&dev->mutex); 1325 1326 /* 1327 * Framework needs to save off AC'97 state. 1328 */ 1329 ac97_suspend(dev->ac97); 1330 1331 return (DDI_SUCCESS); 1332 } 1333 1334 static int 1335 audioens_quiesce(dev_info_t *dip) 1336 { 1337 audioens_dev_t *dev; 1338 uint8_t tmp; 1339 1340 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1341 return (DDI_FAILURE); 1342 } 1343 1344 /* This disables all DMA engines and interrupts */ 1345 tmp = GET8(dev, CONC_bSERCTL_OFF) & 1346 ~(CONC_SERCTL_DAC2IE | CONC_SERCTL_DAC1IE | CONC_SERCTL_ADCIE); 1347 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1348 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1349 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1350 PUT8(dev, CONC_bSERCTL_OFF, tmp); 1351 1352 tmp = GET8(dev, CONC_bDEVCTL_OFF) & 1353 ~(CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_DAC1_EN); 1354 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1355 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1356 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1357 PUT8(dev, CONC_bDEVCTL_OFF, tmp); 1358 1359 return (DDI_SUCCESS); 1360 } 1361 1362 1363 static int 1364 audioens_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 1365 { 1366 audioens_dev_t *dev; 1367 1368 switch (cmd) { 1369 case DDI_ATTACH: 1370 return (audioens_attach(dip)); 1371 1372 case DDI_RESUME: 1373 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1374 return (DDI_FAILURE); 1375 } 1376 return (audioens_resume(dev)); 1377 1378 default: 1379 return (DDI_FAILURE); 1380 } 1381 } 1382 1383 static int 1384 audioens_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 1385 { 1386 audioens_dev_t *dev; 1387 1388 if ((dev = ddi_get_driver_private(dip)) == NULL) { 1389 return (DDI_FAILURE); 1390 } 1391 1392 switch (cmd) { 1393 case DDI_DETACH: 1394 return (audioens_detach(dev)); 1395 1396 case DDI_SUSPEND: 1397 return (audioens_suspend(dev)); 1398 default: 1399 return (DDI_FAILURE); 1400 } 1401 } 1402 1403 static int audioens_ddi_attach(dev_info_t *, ddi_attach_cmd_t); 1404 static int audioens_ddi_detach(dev_info_t *, ddi_detach_cmd_t); 1405 1406 static struct dev_ops audioens_dev_ops = { 1407 DEVO_REV, /* rev */ 1408 0, /* refcnt */ 1409 NULL, /* getinfo */ 1410 nulldev, /* identify */ 1411 nulldev, /* probe */ 1412 audioens_ddi_attach, /* attach */ 1413 audioens_ddi_detach, /* detach */ 1414 nodev, /* reset */ 1415 NULL, /* cb_ops */ 1416 NULL, /* bus_ops */ 1417 NULL, /* power */ 1418 audioens_quiesce, /* quiesce */ 1419 }; 1420 1421 static struct modldrv audioens_modldrv = { 1422 &mod_driverops, /* drv_modops */ 1423 "Ensoniq 1371/1373 Audio", /* linkinfo */ 1424 &audioens_dev_ops, /* dev_ops */ 1425 }; 1426 1427 static struct modlinkage modlinkage = { 1428 MODREV_1, 1429 { &audioens_modldrv, NULL } 1430 }; 1431 1432 int 1433 _init(void) 1434 { 1435 int rv; 1436 1437 audio_init_ops(&audioens_dev_ops, DRVNAME); 1438 if ((rv = mod_install(&modlinkage)) != 0) { 1439 audio_fini_ops(&audioens_dev_ops); 1440 } 1441 return (rv); 1442 } 1443 1444 int 1445 _fini(void) 1446 { 1447 int rv; 1448 1449 if ((rv = mod_remove(&modlinkage)) == 0) { 1450 audio_fini_ops(&audioens_dev_ops); 1451 } 1452 return (rv); 1453 } 1454 1455 int 1456 _info(struct modinfo *modinfop) 1457 { 1458 return (mod_info(&modlinkage, modinfop)); 1459 } 1460