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