xref: /illumos-gate/usr/src/uts/common/io/audio/drv/audioens/audioens.c (revision ef2504f26d1ea5859db9838255bb63f488f1b050)
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