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 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	DEFINTS			75
57 #define	DRVNAME			"audiopci"
58 
59 #define	INPUT_MIC	0
60 #define	INPUT_LINEIN	1
61 #define	INPUT_CD	2
62 #define	INPUT_VIDEO	3
63 #define	INPUT_PHONE	4
64 #define	INSRCS		0x1f		/* bits 0-4 */
65 
66 static const char *audiopci_insrcs[] = {
67 	AUDIO_PORT_MIC,
68 	AUDIO_PORT_LINEIN,
69 	AUDIO_PORT_CD,
70 	AUDIO_PORT_VIDEO,
71 	AUDIO_PORT_PHONE,
72 	NULL
73 };
74 
75 typedef struct audiopci_port
76 {
77 	/* Audio parameters */
78 	boolean_t		trigger;
79 
80 	int			speed;
81 	int			fmt;
82 
83 	int			num;
84 #define	PORT_DAC		0
85 #define	PORT_SYN		1
86 #define	PORT_ADC		2
87 #define	PORT_MAX		PORT_ADC
88 
89 	caddr_t			kaddr;
90 	uint32_t		paddr;
91 	ddi_acc_handle_t	acch;
92 	ddi_dma_handle_t	dmah;
93 	unsigned		fragfr;
94 	unsigned		nfrags;
95 	unsigned		nframes;
96 	unsigned		frameno;
97 	uint64_t		count;
98 
99 	struct audiopci_dev	*dev;
100 	audio_engine_t	*engine;
101 } audiopci_port_t;
102 
103 typedef enum {
104 	CTL_VOLUME = 0,
105 	CTL_FRONT,
106 	CTL_MONO,
107 	CTL_MIC,
108 	CTL_LINE,
109 	CTL_CD,
110 	CTL_VID,
111 	CTL_PHONE,
112 	CTL_MICBOOST,
113 	CTL_RECSRC,
114 	CTL_MONSRC,
115 	CTL_NUM		/* must be last */
116 } audiopci_ctrl_num_t;
117 
118 typedef struct audiopci_ctrl
119 {
120 	struct audiopci_dev	*dev;
121 	audio_ctrl_t		*ctrl;
122 	audiopci_ctrl_num_t	num;
123 	uint64_t		val;
124 } audiopci_ctrl_t;
125 
126 
127 typedef struct audiopci_dev
128 {
129 	audio_dev_t		*adev;
130 	kmutex_t		mutex;
131 	uint16_t		devid;
132 	dev_info_t		*dip;
133 	boolean_t		enabled;
134 	boolean_t		suspended;
135 
136 	int			pintrs;
137 	int			rintrs;
138 
139 	uint8_t			ak_regs[0x20];
140 	int			micbias;
141 
142 	/*
143 	 * Controls
144 	 */
145 	audiopci_ctrl_t		controls[CTL_NUM];
146 #if 0
147 	audiopci_ctrl_t		*micbias;
148 #endif
149 
150 	kstat_t			*ksp;
151 
152 	audiopci_port_t		port[PORT_MAX + 1];
153 
154 
155 	caddr_t			regs;
156 	ddi_acc_handle_t	acch;
157 	ddi_intr_handle_t	ihandle[1];
158 } audiopci_dev_t;
159 
160 static ddi_device_acc_attr_t acc_attr = {
161 	DDI_DEVICE_ATTR_V0,
162 	DDI_STRUCTURE_LE_ACC,
163 	DDI_STRICTORDER_ACC
164 };
165 
166 static ddi_device_acc_attr_t buf_attr = {
167 	DDI_DEVICE_ATTR_V0,
168 	DDI_NEVERSWAP_ACC,
169 	DDI_STRICTORDER_ACC
170 };
171 
172 /*
173  * The hardware appears to be able to address up to 16-bits worth of longwords,
174  * giving a total address space of 256K.  Note, however, that we will restrict
175  * this further when we do fragment and memory allocation.  At its very highest
176  * clock rate (48 kHz) and sample size (16-bit stereo), and lowest interrupt
177  * rate (32 Hz), we only need 6000 bytes per fragment.
178  *
179  * So with an allocated buffer size of 64K, we can support at least 10 frags,
180  * which is more than enough.  (The legacy Sun driver used only 2 fragments.)
181  */
182 #define	AUDIOPCI_BUF_LEN	(65536)
183 
184 static ddi_dma_attr_t dma_attr = {
185 	DMA_ATTR_VERSION,	/* dma_attr_version */
186 	0x0,			/* dma_attr_addr_lo */
187 	0xffffffffU,		/* dma_attr_addr_hi */
188 	0x3ffff,		/* dma_attr_count_max */
189 	0x8,			/* dma_attr_align */
190 	0x7f,			/* dma_attr_burstsizes */
191 	0x1,			/* dma_attr_minxfer */
192 	0x3ffff,		/* dma_attr_maxxfer */
193 	0x3ffff,		/* dma_attr_seg */
194 	0x1,			/* dma_attr_sgllen */
195 	0x1,			/* dma_attr_granular */
196 	0			/* dma_attr_flags */
197 };
198 
199 #define	GET8(dev, offset)	\
200 	ddi_get8(dev->acch, (uint8_t *)(dev->regs + (offset)))
201 #define	GET16(dev, offset)	\
202 	ddi_get16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)))
203 #define	GET32(dev, offset)	\
204 	ddi_get32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)))
205 #define	PUT8(dev, offset, v)	\
206 	ddi_put8(dev->acch, (uint8_t *)(dev->regs + (offset)), v)
207 #define	PUT16(dev, offset, v)	\
208 	ddi_put16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)), v)
209 #define	PUT32(dev, offset, v)	\
210 	ddi_put32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)), v)
211 
212 #define	CLR8(dev, offset, v)	PUT8(dev, offset, GET8(dev, offset) & ~(v))
213 #define	SET8(dev, offset, v)	PUT8(dev, offset, GET8(dev, offset) | (v))
214 #define	CLR16(dev, offset, v)	PUT16(dev, offset, GET16(dev, offset) & ~(v))
215 #define	SET16(dev, offset, v)	PUT16(dev, offset, GET16(dev, offset) | (v))
216 
217 #define	KSINTR(dev)	((kstat_intr_t *)((dev)->ksp->ks_data))
218 
219 static void audiopci_init_hw(audiopci_dev_t *);
220 static void audiopci_init_port(audiopci_port_t *);
221 static void audiopci_start_port(audiopci_port_t *);
222 static void audiopci_stop_port(audiopci_port_t *);
223 static void audiopci_update_port(audiopci_port_t *);
224 static uint16_t audiopci_dac_rate(int);
225 static int audiopci_add_controls(audiopci_dev_t *);
226 static void audiopci_del_controls(audiopci_dev_t *);
227 static void audiopci_ak_write(audiopci_dev_t *, uint16_t, uint8_t);
228 
229 static int
230 audiopci_ak_wait(audiopci_dev_t *dev, uint8_t wstat)
231 {
232 	for (int i = 4000; i; i--) {
233 		if (!(GET8(dev, CONC_bCODECSTAT_OFF) & wstat))
234 			return (DDI_SUCCESS);
235 		drv_usecwait(10);
236 	}
237 	return (DDI_FAILURE);
238 }
239 
240 static void
241 audiopci_ak_idle(audiopci_dev_t *dev)
242 {
243 	for (int i = 0; i < 5; i++) {
244 		if (audiopci_ak_wait(dev, CONC_CSTAT_CSTAT) == DDI_SUCCESS)
245 			return;
246 	}
247 	audio_dev_warn(dev->adev, "timed out waiting for codec to idle");
248 }
249 
250 static void
251 audiopci_ak_write(audiopci_dev_t *dev, uint16_t addr, uint8_t data)
252 {
253 	uint8_t	wstat;
254 
255 	if (dev->suspended)
256 		return;
257 
258 	/* shadow the value */
259 	dev->ak_regs[addr] = data;
260 
261 	wstat = addr == CODEC_RESET_PWRD ? CONC_CSTAT_CWRIP : CONC_CSTAT_CSTAT;
262 
263 	/* wait for codec to be available */
264 	if (audiopci_ak_wait(dev, wstat) != DDI_SUCCESS) {
265 		audio_dev_warn(dev->adev, "timeout waiting for codec");
266 	}
267 
268 	PUT16(dev, CONC_wCODECCTL_OFF, (addr << 8) | data);
269 }
270 
271 static void
272 audiopci_writemem(audiopci_dev_t *dev, uint32_t page, uint32_t offs,
273     uint32_t data)
274 {
275 	/* Select memory page */
276 	PUT32(dev, CONC_bMEMPAGE_OFF, page);
277 	PUT32(dev, offs, data);
278 }
279 
280 static uint32_t
281 audiopci_readmem(audiopci_dev_t *dev, uint32_t page, uint32_t offs)
282 {
283 	PUT32(dev, CONC_bMEMPAGE_OFF, page);	/* Select memory page */
284 	return (GET32(dev, offs));
285 }
286 
287 static uint_t
288 audiopci_intr(caddr_t arg1, caddr_t arg2)
289 {
290 	audiopci_dev_t *dev = (void *)arg1;
291 	int stats;
292 	int tmp;
293 	unsigned char ackbits = 0;
294 	audiopci_port_t *port;
295 	audio_engine_t *do_syn, *do_dac, *do_adc;
296 
297 	_NOTE(ARGUNUSED(arg2));
298 
299 	/*
300 	 * NB: The old driver didn't report spurious interrupts.  On
301 	 * a system with shared interrupts (typical!) there will
302 	 * normally be lots of these (each time the "other" device
303 	 * interrupts).
304 	 *
305 	 * Also, because of the way the interrupt chain handling
306 	 * works, reporting of spurious interrupts is probably not
307 	 * terribly useful.
308 	 *
309 	 * However, we can count interrupts where the master interrupt
310 	 * bit is set but none of the ackbits that we are prepared to
311 	 * process is set.  That is probably useful.
312 	 */
313 	mutex_enter(&dev->mutex);
314 	if (!dev->enabled) {
315 
316 		mutex_exit(&dev->mutex);
317 		return (DDI_INTR_UNCLAIMED);
318 	}
319 
320 	stats = GET32(dev, CONC_dSTATUS_OFF);
321 
322 	if (!(stats & CONC_INTSTAT_PENDING)) {	/* No interrupt pending */
323 		mutex_exit(&dev->mutex);
324 		return (DDI_INTR_UNCLAIMED);
325 	}
326 
327 	do_syn = do_dac = do_adc = NULL;
328 
329 	/* synth interrupt */
330 	if (stats & CONC_INTSTAT_SYNINT) {
331 
332 		ackbits |= CONC_SERCTL_SYNIE;
333 		port = &dev->port[PORT_SYN];
334 		if (port->trigger) {
335 			do_syn = port->engine;
336 		}
337 	}
338 
339 	/* DAC interrupt */
340 	if (stats & CONC_INTSTAT_DACINT) {
341 
342 		ackbits |= CONC_SERCTL_DACIE;
343 		port = &dev->port[PORT_DAC];
344 		if (port->trigger) {
345 			do_dac = port->engine;
346 		}
347 	}
348 
349 	/* ADC interrupt */
350 	if (stats & CONC_INTSTAT_ADCINT) {
351 
352 		ackbits |= CONC_SERCTL_ADCIE;
353 		port = &dev->port[PORT_ADC];
354 
355 		if (port->trigger) {
356 			do_adc = port->engine;
357 		}
358 	}
359 
360 	/* UART interrupt - we shouldn't get this! */
361 	if (stats & CONC_INTSTAT_UARTINT) {
362 		uint8_t uart_stat = GET8(dev, CONC_bUARTCSTAT_OFF);
363 		while (uart_stat & CONC_UART_RXRDY)
364 			uart_stat = GET8(dev, CONC_bUARTCSTAT_OFF);
365 	}
366 
367 	/* Ack the interrupt */
368 	tmp = GET8(dev, CONC_bSERCTL_OFF);
369 	PUT8(dev, CONC_bSERCTL_OFF, tmp & (~ackbits));	/* Clear bits */
370 	PUT8(dev, CONC_bSERCTL_OFF, tmp | ackbits);	/* Turn them back on */
371 
372 	if (dev->ksp) {
373 		if (ackbits == 0) {
374 			KSINTR(dev)->intrs[KSTAT_INTR_SPURIOUS]++;
375 		} else {
376 			KSINTR(dev)->intrs[KSTAT_INTR_HARD]++;
377 		}
378 	}
379 
380 	mutex_exit(&dev->mutex);
381 
382 	if (do_syn)
383 		audio_engine_consume(do_syn);
384 	if (do_dac)
385 		audio_engine_consume(do_dac);
386 	if (do_adc)
387 		audio_engine_produce(do_adc);
388 
389 	return (DDI_INTR_CLAIMED);
390 }
391 
392 /*
393  * Audio routines
394  */
395 
396 static int
397 audiopci_format(void *arg)
398 {
399 	_NOTE(ARGUNUSED(arg));
400 	return (AUDIO_FORMAT_S16_LE);
401 }
402 
403 static int
404 audiopci_channels(void *arg)
405 {
406 	_NOTE(ARGUNUSED(arg));
407 	return (2);
408 }
409 
410 static int
411 audiopci_rate(void *arg)
412 {
413 	audiopci_port_t	*port = arg;
414 
415 	return (port->speed);
416 }
417 
418 static void
419 audiopci_init_port(audiopci_port_t *port)
420 {
421 	audiopci_dev_t	*dev = port->dev;
422 	unsigned tmp;
423 
424 	if (dev->suspended)
425 		return;
426 
427 	switch (port->num) {
428 	case PORT_DAC:
429 
430 		/* Set physical address of the DMA buffer */
431 		audiopci_writemem(dev, CONC_DACCTL_PAGE, CONC_dDACPADDR_OFF,
432 		    port->paddr);
433 
434 		/* Set DAC rate */
435 		PUT16(dev, CONC_wDACRATE_OFF, audiopci_dac_rate(48000));
436 
437 		/* Set format */
438 		tmp = GET8(dev, CONC_bSERFMT_OFF);
439 		tmp |= CONC_PCM_DAC_16BIT;
440 		tmp |= CONC_PCM_DAC_STEREO;
441 
442 		PUT8(dev, CONC_bSKIPC_OFF, 0x10);
443 		PUT8(dev, CONC_bSERFMT_OFF, tmp);
444 
445 		/* Set the frame count */
446 		audiopci_writemem(dev, CONC_DACCTL_PAGE, CONC_wDACFC_OFF,
447 		    port->nframes - 1);
448 
449 		/* Set # of frames between interrupts */
450 		PUT16(dev, CONC_wDACIC_OFF, port->fragfr - 1);
451 
452 		break;
453 
454 	case PORT_SYN:
455 
456 		/* Set physical address of the DMA buffer */
457 		audiopci_writemem(dev, CONC_SYNCTL_PAGE, CONC_dSYNPADDR_OFF,
458 		    port->paddr);
459 
460 		/* Set rate - we force to 44.1 kHz */
461 		SET8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_SYN_44KHZ);
462 
463 		/* Set format */
464 		tmp = GET8(dev, CONC_bSERFMT_OFF);
465 		tmp |= CONC_PCM_SYN_16BIT;
466 		tmp |= CONC_PCM_SYN_STEREO;
467 
468 		PUT8(dev, CONC_bSERFMT_OFF, tmp);
469 
470 		/* Set the frame count */
471 		audiopci_writemem(dev, CONC_SYNCTL_PAGE, CONC_wSYNFC_OFF,
472 		    port->nframes - 1);
473 
474 		/* Set # of frames between interrupts */
475 		PUT16(dev, CONC_wSYNIC_OFF, port->fragfr - 1);
476 
477 		break;
478 
479 	case PORT_ADC:
480 		/* Set physical address of the DMA buffer */
481 		audiopci_writemem(dev, CONC_ADCCTL_PAGE, CONC_dADCPADDR_OFF,
482 		    port->paddr);
483 
484 		/* Set ADC rate */
485 		PUT16(dev, CONC_wDACRATE_OFF, audiopci_dac_rate(48000));
486 
487 		/* Set format - for input we only support 16 bit input */
488 		tmp = GET8(dev, CONC_bSERFMT_OFF);
489 		tmp |= CONC_PCM_ADC_16BIT;
490 		tmp |= CONC_PCM_ADC_STEREO;
491 
492 		PUT8(dev, CONC_bSKIPC_OFF, 0x10);
493 
494 		PUT8(dev, CONC_bSERFMT_OFF, tmp);
495 
496 		/* Set the frame count */
497 		audiopci_writemem(dev, CONC_ADCCTL_PAGE, CONC_wADCFC_OFF,
498 		    port->nframes - 1);
499 
500 		/* Set # of frames between interrupts */
501 		PUT16(dev, CONC_wADCIC_OFF, port->fragfr - 1);
502 
503 		break;
504 	}
505 
506 	port->frameno = 0;
507 }
508 
509 static int
510 audiopci_open(void *arg, int flag, unsigned *fragfrp, unsigned *nfragsp,
511     caddr_t *bufp)
512 {
513 	audiopci_port_t	*port = arg;
514 	audiopci_dev_t	*dev = port->dev;
515 	int intrs;
516 
517 	_NOTE(ARGUNUSED(flag));
518 
519 
520 	mutex_enter(&dev->mutex);
521 	switch (port->num) {
522 	case PORT_ADC:
523 		intrs = dev->rintrs;
524 		break;
525 	case PORT_DAC:
526 		intrs = dev->pintrs;
527 		break;
528 	case PORT_SYN:
529 		intrs = dev->pintrs;
530 		break;
531 	}
532 
533 	/* interrupt at least at 25 Hz, and not more than 250 Hz */
534 	intrs = min(250, max(25, intrs));
535 
536 	/* NB: frame size = 4 (16-bit stereo) */
537 	port->fragfr = (port->speed / intrs);
538 	port->nfrags = AUDIOPCI_BUF_LEN / (port->fragfr * 4);
539 	port->nfrags = max(4, min(port->nfrags, 1024));
540 	port->nframes = port->nfrags * port->fragfr;
541 	port->trigger = B_FALSE;
542 	port->count = 0;
543 
544 	audiopci_init_port(port);
545 
546 	*fragfrp = port->fragfr;
547 	*nfragsp = port->nfrags;
548 	*bufp = port->kaddr;
549 	mutex_exit(&dev->mutex);
550 
551 	return (0);
552 }
553 
554 static void
555 audiopci_start_port(audiopci_port_t *port)
556 {
557 	audiopci_dev_t *dev = port->dev;
558 
559 	if (!dev->suspended) {
560 		switch (port->num) {
561 		case PORT_DAC:
562 			SET8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_DAC_EN);
563 			SET8(dev, CONC_bSERCTL_OFF, CONC_SERCTL_DACIE);
564 			break;
565 		case PORT_SYN:
566 			SET8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_SYN_EN);
567 			SET8(dev, CONC_bSERCTL_OFF, CONC_SERCTL_SYNIE);
568 			break;
569 		case PORT_ADC:
570 			SET8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_ADC_EN);
571 			SET8(dev, CONC_bSERCTL_OFF, CONC_SERCTL_ADCIE);
572 			break;
573 		}
574 	}
575 }
576 
577 static void
578 audiopci_stop_port(audiopci_port_t *port)
579 {
580 	audiopci_dev_t *dev = port->dev;
581 
582 	if (!dev->suspended) {
583 		switch (port->num) {
584 		case PORT_DAC:
585 			CLR8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_DAC_EN);
586 			CLR8(dev, CONC_bSERCTL_OFF, CONC_SERCTL_DACIE);
587 			break;
588 		case PORT_SYN:
589 			CLR8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_SYN_EN);
590 			CLR8(dev, CONC_bSERCTL_OFF, CONC_SERCTL_SYNIE);
591 			break;
592 		case PORT_ADC:
593 			CLR8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_ADC_EN);
594 			CLR8(dev, CONC_bSERCTL_OFF, CONC_SERCTL_ADCIE);
595 			break;
596 		}
597 	}
598 }
599 
600 static int
601 audiopci_start(void *arg)
602 {
603 	audiopci_port_t *port = arg;
604 	audiopci_dev_t *dev = port->dev;
605 
606 	mutex_enter(&dev->mutex);
607 	if (!port->trigger) {
608 		port->trigger = B_TRUE;
609 		audiopci_start_port(port);
610 	}
611 	mutex_exit(&dev->mutex);
612 
613 	return (0);
614 }
615 
616 static void
617 audiopci_stop(void *arg)
618 {
619 	audiopci_port_t *port = arg;
620 	audiopci_dev_t *dev = port->dev;
621 
622 	mutex_enter(&dev->mutex);
623 	if (port->trigger) {
624 		port->trigger = B_FALSE;
625 		audiopci_stop_port(port);
626 	}
627 	mutex_exit(&dev->mutex);
628 }
629 
630 static void
631 audiopci_update_port(audiopci_port_t *port)
632 {
633 	uint32_t page, offs;
634 	int frameno, n;
635 
636 	switch (port->num) {
637 	case PORT_DAC:
638 		page = CONC_DACCTL_PAGE;
639 		offs = CONC_wDACFC_OFF;
640 		break;
641 
642 	case PORT_SYN:
643 		page = CONC_SYNCTL_PAGE;
644 		offs = CONC_wSYNFC_OFF;
645 		break;
646 
647 	case PORT_ADC:
648 		page = CONC_ADCCTL_PAGE;
649 		offs = CONC_wADCFC_OFF;
650 		break;
651 	}
652 
653 	/*
654 	 * Note that the current frame counter is in the high nybble.
655 	 */
656 	frameno = audiopci_readmem(port->dev, page, offs) >> 16;
657 	n = frameno >= port->frameno ?
658 	    frameno - port->frameno :
659 	    frameno + port->nframes - port->frameno;
660 	port->frameno = frameno;
661 	port->count += n;
662 }
663 
664 static uint64_t
665 audiopci_count(void *arg)
666 {
667 	audiopci_port_t *port = arg;
668 	audiopci_dev_t *dev = port->dev;
669 	uint64_t val;
670 
671 	mutex_enter(&dev->mutex);
672 	if (!dev->suspended) {
673 		audiopci_update_port(port);
674 	}
675 	val = port->count;
676 	mutex_exit(&dev->mutex);
677 	return (val);
678 }
679 
680 static void
681 audiopci_close(void *arg)
682 {
683 	audiopci_port_t *port = arg;
684 
685 	audiopci_stop(port);
686 }
687 
688 static void
689 audiopci_sync(void *arg, unsigned nframes)
690 {
691 	audiopci_port_t *port = arg;
692 
693 	_NOTE(ARGUNUSED(nframes));
694 
695 	if (port->num == PORT_ADC) {
696 		(void) ddi_dma_sync(port->dmah, 0, 0, DDI_DMA_SYNC_FORCPU);
697 	} else {
698 		(void) ddi_dma_sync(port->dmah, 0, 0, DDI_DMA_SYNC_FORDEV);
699 	}
700 }
701 
702 audio_engine_ops_t audiopci_engine_ops = {
703 	AUDIO_ENGINE_VERSION,		/* version number */
704 	audiopci_open,
705 	audiopci_close,
706 	audiopci_start,
707 	audiopci_stop,
708 	audiopci_count,
709 	audiopci_format,
710 	audiopci_channels,
711 	audiopci_rate,
712 	audiopci_sync,
713 	NULL,
714 	NULL,
715 	NULL,
716 };
717 
718 static uint16_t
719 audiopci_dac_rate(int samPerSec)
720 {
721 	unsigned short usTemp;
722 
723 	/* samPerSec /= 2; */
724 
725 	usTemp = (unsigned short) ((DAC_CLOCK_DIVIDE / 8) / samPerSec);
726 
727 	if (usTemp & 0x00000001) {
728 		usTemp >>= 1;
729 		usTemp -= 1;
730 	} else {
731 		usTemp >>= 1;
732 		usTemp -= 2;
733 	}
734 	return (usTemp);
735 }
736 
737 void
738 audiopci_init_hw(audiopci_dev_t *dev)
739 {
740 	int tmp;
741 
742 	/* setup DAC frequency */
743 	PUT16(dev, CONC_wDACRATE_OFF, audiopci_dac_rate(48000));
744 
745 	CLR8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_CCB_INTRM);
746 	SET8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_SYN_44KHZ);
747 
748 	/* Turn on CODEC (UART and joystick left disabled) */
749 	tmp = GET8(dev, CONC_bDEVCTL_OFF);
750 	tmp |= CONC_DEVCTL_SERR_DIS;
751 	tmp |= CONC_DEVCTL_CODEC_EN;
752 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
753 
754 	/* Reset the UART */
755 	PUT8(dev, CONC_bUARTCSTAT_OFF, 0x00);
756 
757 	/* Disable NMI */
758 	PUT8(dev, CONC_bNMIENA_OFF, 0);
759 	PUT16(dev, CONC_wNMISTAT_OFF, 0);
760 
761 	/* Initialize serial interface */
762 	PUT8(dev, CONC_bSERCTL_OFF, 0);
763 	PUT8(dev, CONC_bSERFMT_OFF,
764 	    CONC_PCM_SYN_STEREO | CONC_PCM_SYN_16BIT);
765 
766 	/* Unmute codec */
767 	CLR8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_MUTE);
768 
769 	/* mixer initialization */
770 	audiopci_ak_idle(dev);
771 
772 	/* power/reset down the codec */
773 	audiopci_ak_write(dev, CODEC_RESET_PWRD, 0);
774 	drv_usecwait(10);
775 
776 	/* now powerup and bring out of reset */
777 	audiopci_ak_write(dev, CODEC_RESET_PWRD, 0x3);
778 	audiopci_ak_idle(dev);
779 
780 	/* enable PLL for DAC2 */
781 	audiopci_ak_write(dev, CODEC_CLKSELECT, 0);
782 
783 	/* select input mixer */
784 	audiopci_ak_write(dev, CODEC_ADSELECT, 0);
785 
786 	/* mark FM for output mixer */
787 	audiopci_ak_write(dev, CODEC_OUT_SW1, CODEC_OUT_ENABLE_SYNTH);
788 	audiopci_ak_write(dev, CODEC_OUT_SW2, CODEC_OUT_ENABLE_WAVE);
789 
790 	/* initialize some reasonable values for the WAVE and SYNTH inputs */
791 	audiopci_ak_write(dev, CODEC_VOL_WAVE_L, 6);
792 	audiopci_ak_write(dev, CODEC_VOL_WAVE_R, 6);
793 	audiopci_ak_write(dev, CODEC_VOL_SYNTH_L, 6);
794 	audiopci_ak_write(dev, CODEC_VOL_SYNTH_R, 6);
795 
796 	/* enable microphone phantom power */
797 	if (dev->micbias) {
798 		SET16(dev, 2, CONC_DEVCTL_MICBIAS);
799 	}
800 
801 	dev->enabled = B_TRUE;
802 }
803 
804 static int
805 audiopci_init(audiopci_dev_t *dev)
806 {
807 	dev->micbias = 1;
808 
809 	audiopci_init_hw(dev);
810 
811 	dev->pintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
812 	    DDI_PROP_DONTPASS, "play-interrupts", DEFINTS);
813 
814 	dev->rintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
815 	    DDI_PROP_DONTPASS, "record-interrupts", DEFINTS);
816 
817 	for (int i = 0; i <= PORT_MAX; i++) {
818 		audiopci_port_t *port;
819 		unsigned caps;
820 		unsigned dmaflags;
821 		size_t rlen;
822 		ddi_dma_cookie_t c;
823 		unsigned ccnt;
824 
825 		port = &dev->port[i];
826 		port->dev = dev;
827 
828 		switch (i) {
829 		case PORT_SYN:
830 			caps = ENGINE_OUTPUT_CAP;
831 			dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
832 			port->speed = 44100;
833 			break;
834 
835 		case PORT_DAC:
836 			caps = ENGINE_OUTPUT_CAP;
837 			dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
838 			port->speed = 48000;
839 			break;
840 
841 		case PORT_ADC:
842 			caps = ENGINE_INPUT_CAP;
843 			dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT;
844 			port->speed = 48000;
845 			break;
846 		}
847 
848 		port->num = i;
849 
850 		/*
851 		 * Allocate DMA resources.
852 		 */
853 
854 		if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_SLEEP,
855 		    NULL, &port->dmah) != DDI_SUCCESS) {
856 			audio_dev_warn(dev->adev,
857 			    "port %d: dma handle allocation failed", i);
858 			return (DDI_FAILURE);
859 		}
860 		if (ddi_dma_mem_alloc(port->dmah, AUDIOPCI_BUF_LEN, &buf_attr,
861 		    DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &port->kaddr,
862 		    &rlen, &port->acch) != DDI_SUCCESS) {
863 			audio_dev_warn(dev->adev,
864 			    "port %d: dma memory allocation failed", i);
865 			return (DDI_FAILURE);
866 		}
867 		/* ensure that the buffer is zeroed out properly */
868 		bzero(port->kaddr, rlen);
869 		if (ddi_dma_addr_bind_handle(port->dmah, NULL, port->kaddr,
870 		    AUDIOPCI_BUF_LEN, dmaflags, DDI_DMA_SLEEP, NULL,
871 		    &c, &ccnt) != DDI_DMA_MAPPED) {
872 			audio_dev_warn(dev->adev,
873 			    "port %d: dma binding failed", i);
874 			return (DDI_FAILURE);
875 		}
876 		port->paddr = c.dmac_address;
877 
878 		/*
879 		 * Allocate and configure audio engine.
880 		 */
881 		port->engine = audio_engine_alloc(&audiopci_engine_ops, caps);
882 		if (port->engine == NULL) {
883 			audio_dev_warn(dev->adev,
884 			    "port %d: audio_engine_alloc failed", i);
885 			return (DDI_FAILURE);
886 		}
887 
888 		audio_engine_set_private(port->engine, port);
889 		audio_dev_add_engine(dev->adev, port->engine);
890 	}
891 
892 	/*
893 	 * Register audio controls.
894 	 */
895 	if (audiopci_add_controls(dev) == DDI_FAILURE) {
896 		return (DDI_FAILURE);
897 	}
898 
899 	/*
900 	 * Set up kstats for interrupt reporting.
901 	 */
902 	dev->ksp = kstat_create(ddi_driver_name(dev->dip),
903 	    ddi_get_instance(dev->dip), ddi_driver_name(dev->dip),
904 	    "controller", KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT);
905 	if (dev->ksp != NULL) {
906 		kstat_install(dev->ksp);
907 	}
908 
909 	if (audio_dev_register(dev->adev) != DDI_SUCCESS) {
910 		audio_dev_warn(dev->adev,
911 		    "unable to register with audio framework");
912 		return (DDI_FAILURE);
913 	}
914 
915 	return (DDI_SUCCESS);
916 }
917 
918 int
919 audiopci_setup_interrupts(audiopci_dev_t *dev)
920 {
921 	int actual;
922 	uint_t ipri;
923 
924 	if ((ddi_intr_alloc(dev->dip, dev->ihandle, DDI_INTR_TYPE_FIXED,
925 	    0, 1, &actual, DDI_INTR_ALLOC_NORMAL) != DDI_SUCCESS) ||
926 	    (actual != 1)) {
927 		audio_dev_warn(dev->adev, "can't alloc intr handle");
928 		return (DDI_FAILURE);
929 	}
930 
931 	if (ddi_intr_get_pri(dev->ihandle[0], &ipri) != DDI_SUCCESS) {
932 		audio_dev_warn(dev->adev,  "can't determine intr priority");
933 		(void) ddi_intr_free(dev->ihandle[0]);
934 		dev->ihandle[0] = NULL;
935 		return (DDI_FAILURE);
936 	}
937 
938 	if (ddi_intr_add_handler(dev->ihandle[0], audiopci_intr, dev,
939 	    NULL) != DDI_SUCCESS) {
940 		audio_dev_warn(dev->adev, "can't add intr handler");
941 		(void) ddi_intr_free(dev->ihandle[0]);
942 		dev->ihandle[0] = NULL;
943 		return (DDI_FAILURE);
944 	}
945 
946 	mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, DDI_INTR_PRI(ipri));
947 
948 	return (DDI_SUCCESS);
949 }
950 
951 void
952 audiopci_destroy(audiopci_dev_t *dev)
953 {
954 	int	i;
955 
956 	if (dev->ihandle[0] != NULL) {
957 		(void) ddi_intr_disable(dev->ihandle[0]);
958 		(void) ddi_intr_remove_handler(dev->ihandle[0]);
959 		(void) ddi_intr_free(dev->ihandle[0]);
960 		mutex_destroy(&dev->mutex);
961 	}
962 
963 	if (dev->ksp != NULL) {
964 		kstat_delete(dev->ksp);
965 	}
966 
967 	/* free up ports, including DMA resources for ports */
968 	for (i = 0; i <= PORT_MAX; i++) {
969 		audiopci_port_t	*port = &dev->port[i];
970 
971 		if (port->paddr != 0)
972 			(void) ddi_dma_unbind_handle(port->dmah);
973 		if (port->acch != NULL)
974 			ddi_dma_mem_free(&port->acch);
975 		if (port->dmah != NULL)
976 			ddi_dma_free_handle(&port->dmah);
977 
978 		if (port->engine != NULL) {
979 			audio_dev_remove_engine(dev->adev, port->engine);
980 			audio_engine_free(port->engine);
981 		}
982 	}
983 
984 	if (dev->acch != NULL) {
985 		ddi_regs_map_free(&dev->acch);
986 	}
987 
988 	audiopci_del_controls(dev);
989 
990 	if (dev->adev != NULL) {
991 		audio_dev_free(dev->adev);
992 	}
993 
994 	kmem_free(dev, sizeof (*dev));
995 }
996 
997 static void
998 audiopci_stereo(audiopci_dev_t *dev, audiopci_ctrl_num_t num, uint8_t lreg)
999 {
1000 	uint8_t		lval, rval;
1001 	uint8_t		lmute, rmute;
1002 	uint64_t	val;
1003 	uint8_t		rreg;
1004 
1005 	rreg = lreg + 1;
1006 	val = dev->controls[num].val;
1007 	lval = (val & 0xff00) >> 8;
1008 	rval = val & 0xff;
1009 
1010 	lmute = lval ? 0 : CODEC_ATT_MUTE;
1011 	rmute = rval ? 0 : CODEC_ATT_MUTE;
1012 
1013 	/* convert to attenuation & apply mute if appropriate */
1014 	lval = ((((100U - lval) * CODEC_ATT_MAX) / 100) & 0xff) | lmute;
1015 	rval = ((((100U - rval) * CODEC_ATT_MAX) / 100) & 0xff) | rmute;
1016 
1017 	audiopci_ak_write(dev, lreg, lval);
1018 	audiopci_ak_write(dev, rreg, rval);
1019 }
1020 
1021 static void
1022 audiopci_mono(audiopci_dev_t *dev, audiopci_ctrl_num_t num, uint8_t reg)
1023 {
1024 	uint64_t val = (dev->controls[num].val & 0xff);
1025 	uint8_t mute;
1026 
1027 	mute = val ? 0 : CODEC_ATT_MUTE;
1028 	val = ((((100U - val) * CODEC_ATT_MAX) / 100) & 0xff) | mute;
1029 
1030 	audiopci_ak_write(dev, reg, val);
1031 }
1032 
1033 static void
1034 audiopci_mono8(audiopci_dev_t *dev, audiopci_ctrl_num_t num, uint8_t reg)
1035 {
1036 	uint64_t val = (dev->controls[num].val & 0xff);
1037 	uint8_t mute;
1038 
1039 	mute = val ? 0 : CODEC_ATT_MUTE;
1040 	val = ((((100U - val) * CODEC_ATT_MONO) / 100) & 0xff) | mute;
1041 
1042 	audiopci_ak_write(dev, reg, val);
1043 }
1044 
1045 static int
1046 audiopci_get_value(void *arg, uint64_t *val)
1047 {
1048 	audiopci_ctrl_t	*pc = arg;
1049 	audiopci_dev_t	*dev = pc->dev;
1050 
1051 	mutex_enter(&dev->mutex);
1052 	*val = pc->val;
1053 	mutex_exit(&dev->mutex);
1054 	return (0);
1055 }
1056 
1057 static void
1058 audiopci_configure_output(audiopci_dev_t *dev)
1059 {
1060 	uint64_t val;
1061 	uint8_t	tmp;
1062 
1063 	/* PCM/Wave level */
1064 	audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_WAVE_L);
1065 	audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_WAVE_R);
1066 	audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_SYNTH_L);
1067 	audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_SYNTH_R);
1068 
1069 	/* front & mono outputs */
1070 	audiopci_stereo(dev, CTL_FRONT, CODEC_VOL_MASTER_L);
1071 	audiopci_mono8(dev, CTL_MONO, CODEC_VOL_MONO);
1072 
1073 	val = dev->controls[CTL_MONSRC].val;
1074 
1075 	/* setup output monitoring as well */
1076 	tmp = CODEC_OUT_ENABLE_SYNTH;
1077 	if (val & (1U << INPUT_MIC))
1078 		tmp |= CODEC_OUT_ENABLE_MIC;
1079 	if (val & (1U << INPUT_CD))
1080 		tmp |= CODEC_OUT_ENABLE_CD;
1081 	if (val & (1U << INPUT_LINEIN))
1082 		tmp |= CODEC_OUT_ENABLE_AUX;
1083 	audiopci_ak_write(dev, CODEC_OUT_SW1, tmp);
1084 
1085 	tmp = CODEC_OUT_ENABLE_WAVE;
1086 	if (val & (1U << INPUT_VIDEO))
1087 		tmp |= CODEC_OUT_ENABLE_TV;
1088 	if (val & (1U << INPUT_PHONE))
1089 		tmp |= CODEC_OUT_ENABLE_TAD;
1090 	audiopci_ak_write(dev, CODEC_OUT_SW2, tmp);
1091 }
1092 
1093 static void
1094 audiopci_configure_input(audiopci_dev_t *dev)
1095 {
1096 	uint64_t	val = dev->controls[CTL_RECSRC].val;
1097 	uint8_t		tmp;
1098 
1099 	tmp = 0;
1100 	if (val & (1U << INPUT_LINEIN))
1101 		tmp |= CODEC_IN_ENABLE_AUX_L;
1102 	if (val & (1U << INPUT_CD))
1103 		tmp |= CODEC_IN_ENABLE_CD_L;
1104 	if (val & (1U << INPUT_MIC))
1105 		tmp |= CODEC_IN_ENABLE_MIC;
1106 	if (val & (1U << INPUT_PHONE))
1107 		tmp |= CODEC_IN_ENABLE_TAD;
1108 	audiopci_ak_write(dev, CODEC_LIN_SW1, tmp);
1109 
1110 	tmp = 0;
1111 	if (val & (1U << INPUT_LINEIN))
1112 		tmp |= CODEC_IN_ENABLE_AUX_R;
1113 	if (val & (1U << INPUT_CD))
1114 		tmp |= CODEC_IN_ENABLE_CD_R;
1115 	if (val & (1U << INPUT_PHONE))
1116 		tmp |= CODEC_IN_ENABLE_TAD;
1117 	if (val & (1U << INPUT_MIC))
1118 		tmp |= CODEC_IN_ENABLE_MIC;
1119 	audiopci_ak_write(dev, CODEC_RIN_SW1, tmp);
1120 
1121 	tmp = 0;
1122 	if (val & (1U << INPUT_VIDEO))
1123 		tmp |= CODEC_IN_ENABLE_TV_L;
1124 	if (val & (1U << INPUT_MIC))
1125 		tmp |= CODEC_IN_ENABLE_TMIC;
1126 	audiopci_ak_write(dev, CODEC_LIN_SW2, tmp);
1127 
1128 	tmp = 0;
1129 	if (val & (1U << INPUT_VIDEO))
1130 		tmp |= CODEC_IN_ENABLE_TV_R;
1131 	if (val & (1U << INPUT_MIC))
1132 		tmp |= CODEC_IN_ENABLE_TMIC;
1133 	audiopci_ak_write(dev, CODEC_RIN_SW2, tmp);
1134 
1135 	/* configure volumes */
1136 	audiopci_mono(dev, CTL_MIC, CODEC_VOL_MIC);
1137 	audiopci_mono(dev, CTL_PHONE, CODEC_VOL_TAD);
1138 	audiopci_stereo(dev, CTL_LINE, CODEC_VOL_AUX_L);
1139 	audiopci_stereo(dev, CTL_CD, CODEC_VOL_CD_L);
1140 	audiopci_stereo(dev, CTL_VID, CODEC_VOL_TV_L);
1141 
1142 	/* activate 30dB mic boost */
1143 	audiopci_ak_write(dev, CODEC_MICBOOST,
1144 	    dev->controls[CTL_MICBOOST].val ? 1 : 0);
1145 }
1146 
1147 static int
1148 audiopci_set_reclevel(void *arg, uint64_t val)
1149 {
1150 	audiopci_ctrl_t	*pc = arg;
1151 	audiopci_dev_t	*dev = pc->dev;
1152 	uint8_t		l;
1153 	uint8_t		r;
1154 
1155 	l = (val & 0xff00) >> 8;
1156 	r = val & 0xff;
1157 
1158 	if ((l > 100) || (r > 100))
1159 		return (EINVAL);
1160 
1161 	mutex_enter(&dev->mutex);
1162 	pc->val = val;
1163 	audiopci_configure_input(dev);
1164 
1165 	mutex_exit(&dev->mutex);
1166 	return (0);
1167 }
1168 
1169 static int
1170 audiopci_set_micboost(void *arg, uint64_t val)
1171 {
1172 	audiopci_ctrl_t	*pc = arg;
1173 	audiopci_dev_t	*dev = pc->dev;
1174 
1175 	mutex_enter(&dev->mutex);
1176 	pc->val = val;
1177 	audiopci_configure_input(dev);
1178 	mutex_exit(&dev->mutex);
1179 	return (0);
1180 }
1181 
1182 static int
1183 audiopci_set_monsrc(void *arg, uint64_t val)
1184 {
1185 	audiopci_ctrl_t	*pc = arg;
1186 	audiopci_dev_t	*dev = pc->dev;
1187 
1188 	if ((val & ~INSRCS) != 0)
1189 		return (EINVAL);
1190 
1191 	mutex_enter(&dev->mutex);
1192 	pc->val = val;
1193 	audiopci_configure_output(dev);
1194 	mutex_exit(&dev->mutex);
1195 	return (0);
1196 }
1197 
1198 static int
1199 audiopci_set_recsrc(void *arg, uint64_t val)
1200 {
1201 	audiopci_ctrl_t	*pc = arg;
1202 	audiopci_dev_t	*dev = pc->dev;
1203 
1204 	if ((val & ~INSRCS) != 0)
1205 		return (EINVAL);
1206 
1207 	mutex_enter(&dev->mutex);
1208 	pc->val = val;
1209 	audiopci_configure_input(dev);
1210 	mutex_exit(&dev->mutex);
1211 	return (0);
1212 }
1213 
1214 static int
1215 audiopci_set_volume(void *arg, uint64_t val)
1216 {
1217 	audiopci_ctrl_t	*pc = arg;
1218 	audiopci_dev_t	*dev = pc->dev;
1219 
1220 	val &= 0xff;
1221 	if (val > 100)
1222 		return (EINVAL);
1223 
1224 	val = (val & 0xff) | ((val & 0xff) << 8);
1225 
1226 	mutex_enter(&dev->mutex);
1227 	pc->val = val;
1228 	audiopci_configure_output(dev);
1229 	mutex_exit(&dev->mutex);
1230 
1231 	return (0);
1232 }
1233 
1234 static int
1235 audiopci_set_front(void *arg, uint64_t val)
1236 {
1237 	audiopci_ctrl_t	*pc = arg;
1238 	audiopci_dev_t	*dev = pc->dev;
1239 	uint8_t		l;
1240 	uint8_t		r;
1241 
1242 	l = (val & 0xff00) >> 8;
1243 	r = val & 0xff;
1244 
1245 	if ((l > 100) || (r > 100))
1246 		return (EINVAL);
1247 
1248 	mutex_enter(&dev->mutex);
1249 	pc->val = val;
1250 	audiopci_configure_output(dev);
1251 
1252 	mutex_exit(&dev->mutex);
1253 	return (0);
1254 }
1255 
1256 static int
1257 audiopci_set_speaker(void *arg, uint64_t val)
1258 {
1259 	audiopci_ctrl_t	*pc = arg;
1260 	audiopci_dev_t	*dev = pc->dev;
1261 
1262 	val &= 0xff;
1263 
1264 	if (val > 100)
1265 		return (EINVAL);
1266 
1267 	mutex_enter(&dev->mutex);
1268 	pc->val = val;
1269 	audiopci_configure_output(dev);
1270 
1271 	mutex_exit(&dev->mutex);
1272 	return (0);
1273 }
1274 
1275 #define	PLAYCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY)
1276 #define	RECCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC)
1277 #define	MONCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR)
1278 #define	PCMVOL	(PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL)
1279 #define	MAINVOL	(PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL)
1280 #define	RECVOL	(RECCTL | AUDIO_CTRL_FLAG_RECVOL)
1281 
1282 static void
1283 audiopci_alloc_ctrl(audiopci_dev_t *dev, uint32_t num, uint64_t val)
1284 {
1285 	audio_ctrl_desc_t	desc;
1286 	audio_ctrl_wr_t		fn;
1287 	audiopci_ctrl_t		*pc;
1288 
1289 	bzero(&desc, sizeof (desc));
1290 
1291 	pc = &dev->controls[num];
1292 	pc->num = num;
1293 	pc->dev = dev;
1294 
1295 	switch (num) {
1296 	case CTL_VOLUME:
1297 		desc.acd_name = AUDIO_CTRL_ID_VOLUME;
1298 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1299 		desc.acd_minvalue = 0;
1300 		desc.acd_maxvalue = 100;
1301 		desc.acd_flags = PCMVOL;
1302 		fn = audiopci_set_volume;
1303 		break;
1304 
1305 	case CTL_FRONT:
1306 		desc.acd_name = AUDIO_CTRL_ID_LINEOUT;
1307 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1308 		desc.acd_minvalue = 0;
1309 		desc.acd_maxvalue = 100;
1310 		desc.acd_flags = MAINVOL;
1311 		fn = audiopci_set_front;
1312 		break;
1313 
1314 	case CTL_MONO:
1315 		desc.acd_name = AUDIO_CTRL_ID_SPEAKER;
1316 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1317 		desc.acd_minvalue = 0;
1318 		desc.acd_maxvalue = 100;
1319 		desc.acd_flags = MAINVOL;
1320 		fn = audiopci_set_speaker;
1321 		break;
1322 
1323 	case CTL_MIC:
1324 		desc.acd_name = AUDIO_CTRL_ID_MIC;
1325 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1326 		desc.acd_minvalue = 0;
1327 		desc.acd_maxvalue = 100;
1328 		desc.acd_flags = RECVOL;
1329 		fn = audiopci_set_reclevel;
1330 		break;
1331 
1332 	case CTL_LINE:
1333 		desc.acd_name = AUDIO_CTRL_ID_LINEIN;
1334 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1335 		desc.acd_minvalue = 0;
1336 		desc.acd_maxvalue = 100;
1337 		desc.acd_flags = RECVOL;
1338 		fn = audiopci_set_reclevel;
1339 		break;
1340 
1341 	case CTL_CD:
1342 		desc.acd_name = AUDIO_CTRL_ID_CD;
1343 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1344 		desc.acd_minvalue = 0;
1345 		desc.acd_maxvalue = 100;
1346 		desc.acd_flags = RECVOL;
1347 		fn = audiopci_set_reclevel;
1348 		break;
1349 
1350 	case CTL_VID:
1351 		desc.acd_name = AUDIO_CTRL_ID_VIDEO;
1352 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1353 		desc.acd_minvalue = 0;
1354 		desc.acd_maxvalue = 100;
1355 		desc.acd_flags = RECVOL;
1356 		fn = audiopci_set_reclevel;
1357 		break;
1358 
1359 	case CTL_PHONE:
1360 		desc.acd_name = AUDIO_CTRL_ID_PHONE;
1361 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1362 		desc.acd_minvalue = 0;
1363 		desc.acd_maxvalue = 100;
1364 		desc.acd_flags = RECVOL;
1365 		fn = audiopci_set_reclevel;
1366 		break;
1367 
1368 	case CTL_RECSRC:
1369 		desc.acd_name = AUDIO_CTRL_ID_RECSRC;
1370 		desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
1371 		desc.acd_minvalue = INSRCS;
1372 		desc.acd_maxvalue = INSRCS;
1373 		desc.acd_flags = RECCTL | AUDIO_CTRL_FLAG_MULTI;
1374 		for (int i = 0; audiopci_insrcs[i]; i++) {
1375 			desc.acd_enum[i] = audiopci_insrcs[i];
1376 		}
1377 		fn = audiopci_set_recsrc;
1378 		break;
1379 
1380 	case CTL_MONSRC:
1381 		desc.acd_name = AUDIO_CTRL_ID_MONSRC;
1382 		desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
1383 		desc.acd_minvalue = INSRCS;
1384 		desc.acd_maxvalue = INSRCS;
1385 		desc.acd_flags = MONCTL | AUDIO_CTRL_FLAG_MULTI;
1386 		for (int i = 0; audiopci_insrcs[i]; i++) {
1387 			desc.acd_enum[i] = audiopci_insrcs[i];
1388 		}
1389 		fn = audiopci_set_monsrc;
1390 		break;
1391 
1392 	case CTL_MICBOOST:
1393 		desc.acd_name = AUDIO_CTRL_ID_MICBOOST;
1394 		desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN;
1395 		desc.acd_minvalue = 0;
1396 		desc.acd_maxvalue = 100;
1397 		desc.acd_flags = RECCTL;
1398 		fn = audiopci_set_micboost;
1399 		break;
1400 	}
1401 
1402 	pc->val = val;
1403 	pc->ctrl = audio_dev_add_control(dev->adev, &desc,
1404 	    audiopci_get_value, fn, pc);
1405 }
1406 
1407 static int
1408 audiopci_add_controls(audiopci_dev_t *dev)
1409 {
1410 	audiopci_alloc_ctrl(dev, CTL_VOLUME, 75);
1411 	audiopci_alloc_ctrl(dev, CTL_FRONT, ((75) | (75 << 8)));
1412 	audiopci_alloc_ctrl(dev, CTL_MONO, 75);
1413 	audiopci_alloc_ctrl(dev, CTL_MIC, 50);
1414 	audiopci_alloc_ctrl(dev, CTL_LINE, 0);
1415 	audiopci_alloc_ctrl(dev, CTL_CD, 0);
1416 	audiopci_alloc_ctrl(dev, CTL_VID, 0);
1417 	audiopci_alloc_ctrl(dev, CTL_PHONE, 0);
1418 	audiopci_alloc_ctrl(dev, CTL_RECSRC, (1U << INPUT_MIC));
1419 	audiopci_alloc_ctrl(dev, CTL_MONSRC, 0);
1420 	audiopci_alloc_ctrl(dev, CTL_MICBOOST, 1);
1421 
1422 	audiopci_configure_output(dev);
1423 	audiopci_configure_input(dev);
1424 
1425 	return (DDI_SUCCESS);
1426 }
1427 
1428 void
1429 audiopci_del_controls(audiopci_dev_t *dev)
1430 {
1431 	for (int i = 0; i < CTL_NUM; i++) {
1432 		if (dev->controls[i].ctrl) {
1433 			audio_dev_del_control(dev->controls[i].ctrl);
1434 		}
1435 	}
1436 }
1437 
1438 int
1439 audiopci_attach(dev_info_t *dip)
1440 {
1441 	uint16_t pci_command, vendor, device;
1442 	audiopci_dev_t *dev;
1443 	ddi_acc_handle_t pcih;
1444 
1445 	dev = kmem_zalloc(sizeof (*dev), KM_SLEEP);
1446 	dev->dip = dip;
1447 	ddi_set_driver_private(dip, dev);
1448 
1449 	if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) {
1450 		audio_dev_warn(dev->adev, "pci_config_setup failed");
1451 		kmem_free(dev, sizeof (*dev));
1452 		return (DDI_FAILURE);
1453 	}
1454 
1455 	vendor = pci_config_get16(pcih, PCI_CONF_VENID);
1456 	device = pci_config_get16(pcih, PCI_CONF_DEVID);
1457 
1458 	if ((vendor != ENSONIQ_VENDOR_ID && vendor != CREATIVE_VENDOR_ID) ||
1459 	    (device != ENSONIQ_ES1370))
1460 		goto err_exit;
1461 
1462 	dev->devid = device;
1463 
1464 	dev->adev = audio_dev_alloc(dip, 0);
1465 	if (dev->adev == NULL) {
1466 		goto err_exit;
1467 	}
1468 
1469 	audio_dev_set_description(dev->adev, "AudioPCI");
1470 	audio_dev_set_version(dev->adev, "ES1370");
1471 	audio_dev_add_info(dev->adev, "Legacy codec: Asahi Kasei AK4531");
1472 
1473 	/* activate the device */
1474 	pci_command = pci_config_get16(pcih, PCI_CONF_COMM);
1475 	pci_command |= PCI_COMM_ME | PCI_COMM_IO;
1476 	pci_config_put16(pcih, PCI_CONF_COMM, pci_command);
1477 
1478 	/* map registers */
1479 	if (ddi_regs_map_setup(dip, 1, &dev->regs, 0, 0, &acc_attr,
1480 	    &dev->acch) != DDI_SUCCESS) {
1481 		audio_dev_warn(dev->adev, "can't map registers");
1482 		goto err_exit;
1483 	}
1484 
1485 	if (audiopci_setup_interrupts(dev) != DDI_SUCCESS) {
1486 		audio_dev_warn(dev->adev, "can't register interrupts");
1487 		goto err_exit;
1488 	}
1489 
1490 	/* This allocates and configures the engines */
1491 	if (audiopci_init(dev) != DDI_SUCCESS) {
1492 		audio_dev_warn(dev->adev, "can't init device");
1493 		goto err_exit;
1494 	}
1495 
1496 	(void) ddi_intr_enable(dev->ihandle[0]);
1497 
1498 	pci_config_teardown(&pcih);
1499 
1500 	ddi_report_dev(dip);
1501 
1502 	return (DDI_SUCCESS);
1503 
1504 err_exit:
1505 	pci_config_teardown(&pcih);
1506 
1507 	audiopci_destroy(dev);
1508 
1509 	return (DDI_FAILURE);
1510 }
1511 
1512 int
1513 audiopci_detach(audiopci_dev_t *dev)
1514 {
1515 	int tmp;
1516 
1517 	/* first unregister us from the DDI framework, might be busy */
1518 	if (audio_dev_unregister(dev->adev) != DDI_SUCCESS)
1519 		return (DDI_FAILURE);
1520 
1521 	mutex_enter(&dev->mutex);
1522 
1523 	tmp = GET8(dev, CONC_bSERCTL_OFF) &
1524 	    ~(CONC_SERCTL_DACIE | CONC_SERCTL_SYNIE | CONC_SERCTL_ADCIE);
1525 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1526 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1527 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1528 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1529 
1530 	tmp = GET8(dev, CONC_bDEVCTL_OFF) &
1531 	    ~(CONC_DEVCTL_DAC_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_SYN_EN);
1532 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1533 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1534 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1535 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1536 
1537 	dev->enabled = B_FALSE;
1538 
1539 	mutex_exit(&dev->mutex);
1540 
1541 	audiopci_destroy(dev);
1542 
1543 	return (DDI_SUCCESS);
1544 }
1545 
1546 static int
1547 audiopci_resume(audiopci_dev_t *dev)
1548 {
1549 	/* ask framework to reset/relocate engine data */
1550 	for (int i = 0; i <= PORT_MAX; i++) {
1551 		audio_engine_reset(dev->port[i].engine);
1552 	}
1553 
1554 	mutex_enter(&dev->mutex);
1555 	dev->suspended = B_FALSE;
1556 
1557 	/* reinitialize hardware */
1558 	audiopci_init_hw(dev);
1559 
1560 	/* restore mixer settings */
1561 	audiopci_configure_output(dev);
1562 	audiopci_configure_input(dev);
1563 
1564 	/* restart ports */
1565 	for (int i = 0; i < PORT_MAX; i++) {
1566 		audiopci_port_t	*port = &dev->port[i];
1567 		audiopci_init_port(port);
1568 		/* possibly start it up if was going when we suspended */
1569 		if (port->trigger) {
1570 			audiopci_start_port(port);
1571 
1572 			/* signal callbacks on resume */
1573 			if (port->num == PORT_ADC) {
1574 				audio_engine_produce(port->engine);
1575 			} else {
1576 				audio_engine_consume(port->engine);
1577 			}
1578 		}
1579 	}
1580 	mutex_exit(&dev->mutex);
1581 	return (DDI_SUCCESS);
1582 }
1583 
1584 static int
1585 audiopci_suspend(audiopci_dev_t *dev)
1586 {
1587 	/*
1588 	 * Stop all engines/DMA data.
1589 	 */
1590 	mutex_enter(&dev->mutex);
1591 	for (int i = 0; i <= PORT_MAX; i++) {
1592 		audiopci_stop_port(&dev->port[i]);
1593 		audiopci_update_port(&dev->port[i]);
1594 	}
1595 	dev->suspended = B_TRUE;
1596 	dev->enabled = B_FALSE;
1597 	mutex_exit(&dev->mutex);
1598 
1599 	return (DDI_SUCCESS);
1600 }
1601 
1602 static int
1603 audiopci_quiesce(dev_info_t *dip)
1604 {
1605 	audiopci_dev_t	*dev;
1606 	uint8_t		tmp;
1607 
1608 	if ((dev = ddi_get_driver_private(dip)) == NULL) {
1609 		return (DDI_FAILURE);
1610 	}
1611 
1612 	/* This disables all DMA engines and interrupts */
1613 	tmp = GET8(dev, CONC_bSERCTL_OFF) &
1614 	    ~(CONC_SERCTL_DACIE | CONC_SERCTL_SYNIE | CONC_SERCTL_ADCIE);
1615 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1616 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1617 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1618 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1619 
1620 	tmp = GET8(dev, CONC_bDEVCTL_OFF) &
1621 	    ~(CONC_DEVCTL_DAC_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_SYN_EN);
1622 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1623 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1624 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1625 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1626 
1627 	return (DDI_SUCCESS);
1628 }
1629 
1630 
1631 static int
1632 audiopci_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1633 {
1634 	audiopci_dev_t *dev;
1635 
1636 	switch (cmd) {
1637 	case DDI_ATTACH:
1638 		return (audiopci_attach(dip));
1639 
1640 	case DDI_RESUME:
1641 		if ((dev = ddi_get_driver_private(dip)) == NULL) {
1642 			return (DDI_FAILURE);
1643 		}
1644 		return (audiopci_resume(dev));
1645 
1646 	default:
1647 		return (DDI_FAILURE);
1648 	}
1649 }
1650 
1651 static int
1652 audiopci_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1653 {
1654 	audiopci_dev_t *dev;
1655 
1656 	if ((dev = ddi_get_driver_private(dip)) == NULL) {
1657 		return (DDI_FAILURE);
1658 	}
1659 
1660 	switch (cmd) {
1661 	case DDI_DETACH:
1662 		return (audiopci_detach(dev));
1663 
1664 	case DDI_SUSPEND:
1665 		return (audiopci_suspend(dev));
1666 	default:
1667 		return (DDI_FAILURE);
1668 	}
1669 }
1670 
1671 static struct dev_ops audiopci_dev_ops = {
1672 	DEVO_REV,		/* rev */
1673 	0,			/* refcnt */
1674 	NULL,			/* getinfo */
1675 	nulldev,		/* identify */
1676 	nulldev,		/* probe */
1677 	audiopci_ddi_attach,	/* attach */
1678 	audiopci_ddi_detach,	/* detach */
1679 	nodev,			/* reset */
1680 	NULL,			/* cb_ops */
1681 	NULL,			/* bus_ops */
1682 	NULL,			/* power */
1683 	audiopci_quiesce,	/* quiesce */
1684 };
1685 
1686 static struct modldrv audiopci_modldrv = {
1687 	&mod_driverops,			/* drv_modops */
1688 	"Ensoniq 1370 Audio",		/* linkinfo */
1689 	&audiopci_dev_ops,		/* dev_ops */
1690 };
1691 
1692 static struct modlinkage modlinkage = {
1693 	MODREV_1,
1694 	{ &audiopci_modldrv, NULL }
1695 };
1696 
1697 int
1698 _init(void)
1699 {
1700 	int	rv;
1701 
1702 	audio_init_ops(&audiopci_dev_ops, DRVNAME);
1703 	if ((rv = mod_install(&modlinkage)) != 0) {
1704 		audio_fini_ops(&audiopci_dev_ops);
1705 	}
1706 	return (rv);
1707 }
1708 
1709 int
1710 _fini(void)
1711 {
1712 	int	rv;
1713 
1714 	if ((rv = mod_remove(&modlinkage)) == 0) {
1715 		audio_fini_ops(&audiopci_dev_ops);
1716 	}
1717 	return (rv);
1718 }
1719 
1720 int
1721 _info(struct modinfo *modinfop)
1722 {
1723 	return (mod_info(&modlinkage, modinfop));
1724 }
1725