xref: /illumos-gate/usr/src/uts/common/io/audio/drv/audiopci/audiopci.c (revision 07a48826732249fcd3aa8dd53c8389595e9f1fbc)
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 static size_t
703 audiopci_qlen(void *arg)
704 {
705 	_NOTE(ARGUNUSED(arg));
706 
707 	/*
708 	 * There is actually a small FIFO with 64 bytes -- 16 samples --
709 	 * onboard, but it is probably not worth the effort to report it,
710 	 * and the FIFO will not always be full.
711 	 */
712 	return (0);
713 }
714 
715 audio_engine_ops_t audiopci_engine_ops = {
716 	AUDIO_ENGINE_VERSION,		/* version number */
717 	audiopci_open,
718 	audiopci_close,
719 	audiopci_start,
720 	audiopci_stop,
721 	audiopci_count,
722 	audiopci_format,
723 	audiopci_channels,
724 	audiopci_rate,
725 	audiopci_sync,
726 	audiopci_qlen,
727 	NULL,
728 };
729 
730 static uint16_t
731 audiopci_dac_rate(int samPerSec)
732 {
733 	unsigned short usTemp;
734 
735 	/* samPerSec /= 2; */
736 
737 	usTemp = (unsigned short) ((DAC_CLOCK_DIVIDE / 8) / samPerSec);
738 
739 	if (usTemp & 0x00000001) {
740 		usTemp >>= 1;
741 		usTemp -= 1;
742 	} else {
743 		usTemp >>= 1;
744 		usTemp -= 2;
745 	}
746 	return (usTemp);
747 }
748 
749 void
750 audiopci_init_hw(audiopci_dev_t *dev)
751 {
752 	int tmp;
753 
754 	/* setup DAC frequency */
755 	PUT16(dev, CONC_wDACRATE_OFF, audiopci_dac_rate(48000));
756 
757 	CLR8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_CCB_INTRM);
758 	SET8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_SYN_44KHZ);
759 
760 	/* Turn on CODEC (UART and joystick left disabled) */
761 	tmp = GET8(dev, CONC_bDEVCTL_OFF);
762 	tmp |= CONC_DEVCTL_SERR_DIS;
763 	tmp |= CONC_DEVCTL_CODEC_EN;
764 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
765 
766 	/* Reset the UART */
767 	PUT8(dev, CONC_bUARTCSTAT_OFF, 0x00);
768 
769 	/* Disable NMI */
770 	PUT8(dev, CONC_bNMIENA_OFF, 0);
771 	PUT16(dev, CONC_wNMISTAT_OFF, 0);
772 
773 	/* Initialize serial interface */
774 	PUT8(dev, CONC_bSERCTL_OFF, 0);
775 	PUT8(dev, CONC_bSERFMT_OFF,
776 	    CONC_PCM_SYN_STEREO | CONC_PCM_SYN_16BIT);
777 
778 	/* Unmute codec */
779 	CLR8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_MUTE);
780 
781 	/* mixer initialization */
782 	audiopci_ak_idle(dev);
783 
784 	/* power/reset down the codec */
785 	audiopci_ak_write(dev, CODEC_RESET_PWRD, 0);
786 	drv_usecwait(10);
787 
788 	/* now powerup and bring out of reset */
789 	audiopci_ak_write(dev, CODEC_RESET_PWRD, 0x3);
790 	audiopci_ak_idle(dev);
791 
792 	/* enable PLL for DAC2 */
793 	audiopci_ak_write(dev, CODEC_CLKSELECT, 0);
794 
795 	/* select input mixer */
796 	audiopci_ak_write(dev, CODEC_ADSELECT, 0);
797 
798 	/* mark FM for output mixer */
799 	audiopci_ak_write(dev, CODEC_OUT_SW1, CODEC_OUT_ENABLE_SYNTH);
800 	audiopci_ak_write(dev, CODEC_OUT_SW2, CODEC_OUT_ENABLE_WAVE);
801 
802 	/* initialize some reasonable values for the WAVE and SYNTH inputs */
803 	audiopci_ak_write(dev, CODEC_VOL_WAVE_L, 6);
804 	audiopci_ak_write(dev, CODEC_VOL_WAVE_R, 6);
805 	audiopci_ak_write(dev, CODEC_VOL_SYNTH_L, 6);
806 	audiopci_ak_write(dev, CODEC_VOL_SYNTH_R, 6);
807 
808 	/* enable microphone phantom power */
809 	if (dev->micbias) {
810 		SET16(dev, 2, CONC_DEVCTL_MICBIAS);
811 	}
812 
813 	dev->enabled = B_TRUE;
814 }
815 
816 static int
817 audiopci_init(audiopci_dev_t *dev)
818 {
819 	dev->micbias = 1;
820 
821 	audiopci_init_hw(dev);
822 
823 	dev->pintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
824 	    DDI_PROP_DONTPASS, "play-interrupts", DEFINTS);
825 
826 	dev->rintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
827 	    DDI_PROP_DONTPASS, "record-interrupts", DEFINTS);
828 
829 	for (int i = 0; i <= PORT_MAX; i++) {
830 		audiopci_port_t *port;
831 		unsigned caps;
832 		unsigned dmaflags;
833 		size_t rlen;
834 		ddi_dma_cookie_t c;
835 		unsigned ccnt;
836 
837 		port = &dev->port[i];
838 		port->dev = dev;
839 
840 		switch (i) {
841 		case PORT_SYN:
842 			caps = ENGINE_OUTPUT_CAP;
843 			dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
844 			port->speed = 44100;
845 			break;
846 
847 		case PORT_DAC:
848 			caps = ENGINE_OUTPUT_CAP;
849 			dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
850 			port->speed = 48000;
851 			break;
852 
853 		case PORT_ADC:
854 			caps = ENGINE_INPUT_CAP;
855 			dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT;
856 			port->speed = 48000;
857 			break;
858 		}
859 
860 		port->num = i;
861 
862 		/*
863 		 * Allocate DMA resources.
864 		 */
865 
866 		if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_SLEEP,
867 		    NULL, &port->dmah) != DDI_SUCCESS) {
868 			audio_dev_warn(dev->adev,
869 			    "port %d: dma handle allocation failed", i);
870 			return (DDI_FAILURE);
871 		}
872 		if (ddi_dma_mem_alloc(port->dmah, AUDIOPCI_BUF_LEN, &buf_attr,
873 		    DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &port->kaddr,
874 		    &rlen, &port->acch) != DDI_SUCCESS) {
875 			audio_dev_warn(dev->adev,
876 			    "port %d: dma memory allocation failed", i);
877 			return (DDI_FAILURE);
878 		}
879 		/* ensure that the buffer is zeroed out properly */
880 		bzero(port->kaddr, rlen);
881 		if (ddi_dma_addr_bind_handle(port->dmah, NULL, port->kaddr,
882 		    AUDIOPCI_BUF_LEN, dmaflags, DDI_DMA_SLEEP, NULL,
883 		    &c, &ccnt) != DDI_DMA_MAPPED) {
884 			audio_dev_warn(dev->adev,
885 			    "port %d: dma binding failed", i);
886 			return (DDI_FAILURE);
887 		}
888 		port->paddr = c.dmac_address;
889 
890 		/*
891 		 * Allocate and configure audio engine.
892 		 */
893 		port->engine = audio_engine_alloc(&audiopci_engine_ops, caps);
894 		if (port->engine == NULL) {
895 			audio_dev_warn(dev->adev,
896 			    "port %d: audio_engine_alloc failed", i);
897 			return (DDI_FAILURE);
898 		}
899 
900 		audio_engine_set_private(port->engine, port);
901 		audio_dev_add_engine(dev->adev, port->engine);
902 	}
903 
904 	/*
905 	 * Register audio controls.
906 	 */
907 	if (audiopci_add_controls(dev) == DDI_FAILURE) {
908 		return (DDI_FAILURE);
909 	}
910 
911 	/*
912 	 * Set up kstats for interrupt reporting.
913 	 */
914 	dev->ksp = kstat_create(ddi_driver_name(dev->dip),
915 	    ddi_get_instance(dev->dip), ddi_driver_name(dev->dip),
916 	    "controller", KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT);
917 	if (dev->ksp != NULL) {
918 		kstat_install(dev->ksp);
919 	}
920 
921 	if (audio_dev_register(dev->adev) != DDI_SUCCESS) {
922 		audio_dev_warn(dev->adev,
923 		    "unable to register with audio framework");
924 		return (DDI_FAILURE);
925 	}
926 
927 	return (DDI_SUCCESS);
928 }
929 
930 int
931 audiopci_setup_interrupts(audiopci_dev_t *dev)
932 {
933 	int actual;
934 	uint_t ipri;
935 
936 	if ((ddi_intr_alloc(dev->dip, dev->ihandle, DDI_INTR_TYPE_FIXED,
937 	    0, 1, &actual, DDI_INTR_ALLOC_NORMAL) != DDI_SUCCESS) ||
938 	    (actual != 1)) {
939 		audio_dev_warn(dev->adev, "can't alloc intr handle");
940 		return (DDI_FAILURE);
941 	}
942 
943 	if (ddi_intr_get_pri(dev->ihandle[0], &ipri) != DDI_SUCCESS) {
944 		audio_dev_warn(dev->adev,  "can't determine intr priority");
945 		(void) ddi_intr_free(dev->ihandle[0]);
946 		dev->ihandle[0] = NULL;
947 		return (DDI_FAILURE);
948 	}
949 
950 	if (ddi_intr_add_handler(dev->ihandle[0], audiopci_intr, dev,
951 	    NULL) != DDI_SUCCESS) {
952 		audio_dev_warn(dev->adev, "can't add intr handler");
953 		(void) ddi_intr_free(dev->ihandle[0]);
954 		dev->ihandle[0] = NULL;
955 		return (DDI_FAILURE);
956 	}
957 
958 	mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, DDI_INTR_PRI(ipri));
959 
960 	return (DDI_SUCCESS);
961 }
962 
963 void
964 audiopci_destroy(audiopci_dev_t *dev)
965 {
966 	int	i;
967 
968 	if (dev->ihandle[0] != NULL) {
969 		(void) ddi_intr_disable(dev->ihandle[0]);
970 		(void) ddi_intr_remove_handler(dev->ihandle[0]);
971 		(void) ddi_intr_free(dev->ihandle[0]);
972 		mutex_destroy(&dev->mutex);
973 	}
974 
975 	if (dev->ksp != NULL) {
976 		kstat_delete(dev->ksp);
977 	}
978 
979 	/* free up ports, including DMA resources for ports */
980 	for (i = 0; i <= PORT_MAX; i++) {
981 		audiopci_port_t	*port = &dev->port[i];
982 
983 		if (port->paddr != 0)
984 			(void) ddi_dma_unbind_handle(port->dmah);
985 		if (port->acch != NULL)
986 			ddi_dma_mem_free(&port->acch);
987 		if (port->dmah != NULL)
988 			ddi_dma_free_handle(&port->dmah);
989 
990 		if (port->engine != NULL) {
991 			audio_dev_remove_engine(dev->adev, port->engine);
992 			audio_engine_free(port->engine);
993 		}
994 	}
995 
996 	if (dev->acch != NULL) {
997 		ddi_regs_map_free(&dev->acch);
998 	}
999 
1000 	audiopci_del_controls(dev);
1001 
1002 	if (dev->adev != NULL) {
1003 		audio_dev_free(dev->adev);
1004 	}
1005 
1006 	kmem_free(dev, sizeof (*dev));
1007 }
1008 
1009 static void
1010 audiopci_stereo(audiopci_dev_t *dev, audiopci_ctrl_num_t num, uint8_t lreg)
1011 {
1012 	uint8_t		lval, rval;
1013 	uint8_t		lmute, rmute;
1014 	uint64_t	val;
1015 	uint8_t		rreg;
1016 
1017 	rreg = lreg + 1;
1018 	val = dev->controls[num].val;
1019 	lval = (val & 0xff00) >> 8;
1020 	rval = val & 0xff;
1021 
1022 	lmute = lval ? 0 : CODEC_ATT_MUTE;
1023 	rmute = rval ? 0 : CODEC_ATT_MUTE;
1024 
1025 	/* convert to attenuation & apply mute if appropriate */
1026 	lval = ((((100U - lval) * CODEC_ATT_MAX) / 100) & 0xff) | lmute;
1027 	rval = ((((100U - rval) * CODEC_ATT_MAX) / 100) & 0xff) | rmute;
1028 
1029 	audiopci_ak_write(dev, lreg, lval);
1030 	audiopci_ak_write(dev, rreg, rval);
1031 }
1032 
1033 static void
1034 audiopci_mono(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_MAX) / 100) & 0xff) | mute;
1041 
1042 	audiopci_ak_write(dev, reg, val);
1043 }
1044 
1045 static void
1046 audiopci_mono8(audiopci_dev_t *dev, audiopci_ctrl_num_t num, uint8_t reg)
1047 {
1048 	uint64_t val = (dev->controls[num].val & 0xff);
1049 	uint8_t mute;
1050 
1051 	mute = val ? 0 : CODEC_ATT_MUTE;
1052 	val = ((((100U - val) * CODEC_ATT_MONO) / 100) & 0xff) | mute;
1053 
1054 	audiopci_ak_write(dev, reg, val);
1055 }
1056 
1057 static int
1058 audiopci_get_value(void *arg, uint64_t *val)
1059 {
1060 	audiopci_ctrl_t	*pc = arg;
1061 	audiopci_dev_t	*dev = pc->dev;
1062 
1063 	mutex_enter(&dev->mutex);
1064 	*val = pc->val;
1065 	mutex_exit(&dev->mutex);
1066 	return (0);
1067 }
1068 
1069 static void
1070 audiopci_configure_output(audiopci_dev_t *dev)
1071 {
1072 	uint64_t val;
1073 	uint8_t	tmp;
1074 
1075 	/* PCM/Wave level */
1076 	audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_WAVE_L);
1077 	audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_WAVE_R);
1078 	audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_SYNTH_L);
1079 	audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_SYNTH_R);
1080 
1081 	/* front & mono outputs */
1082 	audiopci_stereo(dev, CTL_FRONT, CODEC_VOL_MASTER_L);
1083 	audiopci_mono8(dev, CTL_MONO, CODEC_VOL_MONO);
1084 
1085 	val = dev->controls[CTL_MONSRC].val;
1086 
1087 	/* setup output monitoring as well */
1088 	tmp = CODEC_OUT_ENABLE_SYNTH;
1089 	if (val & (1U << INPUT_MIC))
1090 		tmp |= CODEC_OUT_ENABLE_MIC;
1091 	if (val & (1U << INPUT_CD))
1092 		tmp |= CODEC_OUT_ENABLE_CD;
1093 	if (val & (1U << INPUT_LINEIN))
1094 		tmp |= CODEC_OUT_ENABLE_AUX;
1095 	audiopci_ak_write(dev, CODEC_OUT_SW1, tmp);
1096 
1097 	tmp = CODEC_OUT_ENABLE_WAVE;
1098 	if (val & (1U << INPUT_VIDEO))
1099 		tmp |= CODEC_OUT_ENABLE_TV;
1100 	if (val & (1U << INPUT_PHONE))
1101 		tmp |= CODEC_OUT_ENABLE_TAD;
1102 	audiopci_ak_write(dev, CODEC_OUT_SW2, tmp);
1103 }
1104 
1105 static void
1106 audiopci_configure_input(audiopci_dev_t *dev)
1107 {
1108 	uint64_t	val = dev->controls[CTL_RECSRC].val;
1109 	uint8_t		tmp;
1110 
1111 	tmp = 0;
1112 	if (val & (1U << INPUT_LINEIN))
1113 		tmp |= CODEC_IN_ENABLE_AUX_L;
1114 	if (val & (1U << INPUT_CD))
1115 		tmp |= CODEC_IN_ENABLE_CD_L;
1116 	if (val & (1U << INPUT_MIC))
1117 		tmp |= CODEC_IN_ENABLE_MIC;
1118 	if (val & (1U << INPUT_PHONE))
1119 		tmp |= CODEC_IN_ENABLE_TAD;
1120 	audiopci_ak_write(dev, CODEC_LIN_SW1, tmp);
1121 
1122 	tmp = 0;
1123 	if (val & (1U << INPUT_LINEIN))
1124 		tmp |= CODEC_IN_ENABLE_AUX_R;
1125 	if (val & (1U << INPUT_CD))
1126 		tmp |= CODEC_IN_ENABLE_CD_R;
1127 	if (val & (1U << INPUT_PHONE))
1128 		tmp |= CODEC_IN_ENABLE_TAD;
1129 	if (val & (1U << INPUT_MIC))
1130 		tmp |= CODEC_IN_ENABLE_MIC;
1131 	audiopci_ak_write(dev, CODEC_RIN_SW1, tmp);
1132 
1133 	tmp = 0;
1134 	if (val & (1U << INPUT_VIDEO))
1135 		tmp |= CODEC_IN_ENABLE_TV_L;
1136 	if (val & (1U << INPUT_MIC))
1137 		tmp |= CODEC_IN_ENABLE_TMIC;
1138 	audiopci_ak_write(dev, CODEC_LIN_SW2, tmp);
1139 
1140 	tmp = 0;
1141 	if (val & (1U << INPUT_VIDEO))
1142 		tmp |= CODEC_IN_ENABLE_TV_R;
1143 	if (val & (1U << INPUT_MIC))
1144 		tmp |= CODEC_IN_ENABLE_TMIC;
1145 	audiopci_ak_write(dev, CODEC_RIN_SW2, tmp);
1146 
1147 	/* configure volumes */
1148 	audiopci_mono(dev, CTL_MIC, CODEC_VOL_MIC);
1149 	audiopci_mono(dev, CTL_PHONE, CODEC_VOL_TAD);
1150 	audiopci_stereo(dev, CTL_LINE, CODEC_VOL_AUX_L);
1151 	audiopci_stereo(dev, CTL_CD, CODEC_VOL_CD_L);
1152 	audiopci_stereo(dev, CTL_VID, CODEC_VOL_TV_L);
1153 
1154 	/* activate 30dB mic boost */
1155 	audiopci_ak_write(dev, CODEC_MICBOOST,
1156 	    dev->controls[CTL_MICBOOST].val ? 1 : 0);
1157 }
1158 
1159 static int
1160 audiopci_set_reclevel(void *arg, uint64_t val)
1161 {
1162 	audiopci_ctrl_t	*pc = arg;
1163 	audiopci_dev_t	*dev = pc->dev;
1164 	uint8_t		l;
1165 	uint8_t		r;
1166 
1167 	l = (val & 0xff00) >> 8;
1168 	r = val & 0xff;
1169 
1170 	if ((l > 100) || (r > 100))
1171 		return (EINVAL);
1172 
1173 	mutex_enter(&dev->mutex);
1174 	pc->val = val;
1175 	audiopci_configure_input(dev);
1176 
1177 	mutex_exit(&dev->mutex);
1178 	return (0);
1179 }
1180 
1181 static int
1182 audiopci_set_micboost(void *arg, uint64_t val)
1183 {
1184 	audiopci_ctrl_t	*pc = arg;
1185 	audiopci_dev_t	*dev = pc->dev;
1186 
1187 	mutex_enter(&dev->mutex);
1188 	pc->val = val;
1189 	audiopci_configure_input(dev);
1190 	mutex_exit(&dev->mutex);
1191 	return (0);
1192 }
1193 
1194 static int
1195 audiopci_set_monsrc(void *arg, uint64_t val)
1196 {
1197 	audiopci_ctrl_t	*pc = arg;
1198 	audiopci_dev_t	*dev = pc->dev;
1199 
1200 	if ((val & ~INSRCS) != 0)
1201 		return (EINVAL);
1202 
1203 	mutex_enter(&dev->mutex);
1204 	pc->val = val;
1205 	audiopci_configure_output(dev);
1206 	mutex_exit(&dev->mutex);
1207 	return (0);
1208 }
1209 
1210 static int
1211 audiopci_set_recsrc(void *arg, uint64_t val)
1212 {
1213 	audiopci_ctrl_t	*pc = arg;
1214 	audiopci_dev_t	*dev = pc->dev;
1215 
1216 	if ((val & ~INSRCS) != 0)
1217 		return (EINVAL);
1218 
1219 	mutex_enter(&dev->mutex);
1220 	pc->val = val;
1221 	audiopci_configure_input(dev);
1222 	mutex_exit(&dev->mutex);
1223 	return (0);
1224 }
1225 
1226 static int
1227 audiopci_set_volume(void *arg, uint64_t val)
1228 {
1229 	audiopci_ctrl_t	*pc = arg;
1230 	audiopci_dev_t	*dev = pc->dev;
1231 
1232 	val &= 0xff;
1233 	if (val > 100)
1234 		return (EINVAL);
1235 
1236 	val = (val & 0xff) | ((val & 0xff) << 8);
1237 
1238 	mutex_enter(&dev->mutex);
1239 	pc->val = val;
1240 	audiopci_configure_output(dev);
1241 	mutex_exit(&dev->mutex);
1242 
1243 	return (0);
1244 }
1245 
1246 static int
1247 audiopci_set_front(void *arg, uint64_t val)
1248 {
1249 	audiopci_ctrl_t	*pc = arg;
1250 	audiopci_dev_t	*dev = pc->dev;
1251 	uint8_t		l;
1252 	uint8_t		r;
1253 
1254 	l = (val & 0xff00) >> 8;
1255 	r = val & 0xff;
1256 
1257 	if ((l > 100) || (r > 100))
1258 		return (EINVAL);
1259 
1260 	mutex_enter(&dev->mutex);
1261 	pc->val = val;
1262 	audiopci_configure_output(dev);
1263 
1264 	mutex_exit(&dev->mutex);
1265 	return (0);
1266 }
1267 
1268 static int
1269 audiopci_set_speaker(void *arg, uint64_t val)
1270 {
1271 	audiopci_ctrl_t	*pc = arg;
1272 	audiopci_dev_t	*dev = pc->dev;
1273 
1274 	val &= 0xff;
1275 
1276 	if (val > 100)
1277 		return (EINVAL);
1278 
1279 	mutex_enter(&dev->mutex);
1280 	pc->val = val;
1281 	audiopci_configure_output(dev);
1282 
1283 	mutex_exit(&dev->mutex);
1284 	return (0);
1285 }
1286 
1287 #define	PLAYCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY)
1288 #define	RECCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC)
1289 #define	MONCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR)
1290 #define	PCMVOL	(PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL)
1291 #define	MAINVOL	(PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL)
1292 #define	RECVOL	(RECCTL | AUDIO_CTRL_FLAG_RECVOL)
1293 
1294 static void
1295 audiopci_alloc_ctrl(audiopci_dev_t *dev, uint32_t num, uint64_t val)
1296 {
1297 	audio_ctrl_desc_t	desc;
1298 	audio_ctrl_wr_t		fn;
1299 	audiopci_ctrl_t		*pc;
1300 
1301 	bzero(&desc, sizeof (desc));
1302 
1303 	pc = &dev->controls[num];
1304 	pc->num = num;
1305 	pc->dev = dev;
1306 
1307 	switch (num) {
1308 	case CTL_VOLUME:
1309 		desc.acd_name = AUDIO_CTRL_ID_VOLUME;
1310 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1311 		desc.acd_minvalue = 0;
1312 		desc.acd_maxvalue = 100;
1313 		desc.acd_flags = PCMVOL;
1314 		fn = audiopci_set_volume;
1315 		break;
1316 
1317 	case CTL_FRONT:
1318 		desc.acd_name = AUDIO_CTRL_ID_LINEOUT;
1319 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1320 		desc.acd_minvalue = 0;
1321 		desc.acd_maxvalue = 100;
1322 		desc.acd_flags = MAINVOL;
1323 		fn = audiopci_set_front;
1324 		break;
1325 
1326 	case CTL_MONO:
1327 		desc.acd_name = AUDIO_CTRL_ID_SPEAKER;
1328 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1329 		desc.acd_minvalue = 0;
1330 		desc.acd_maxvalue = 100;
1331 		desc.acd_flags = MAINVOL;
1332 		fn = audiopci_set_speaker;
1333 		break;
1334 
1335 	case CTL_MIC:
1336 		desc.acd_name = AUDIO_CTRL_ID_MIC;
1337 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1338 		desc.acd_minvalue = 0;
1339 		desc.acd_maxvalue = 100;
1340 		desc.acd_flags = RECVOL;
1341 		fn = audiopci_set_reclevel;
1342 		break;
1343 
1344 	case CTL_LINE:
1345 		desc.acd_name = AUDIO_CTRL_ID_LINEIN;
1346 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1347 		desc.acd_minvalue = 0;
1348 		desc.acd_maxvalue = 100;
1349 		desc.acd_flags = RECVOL;
1350 		fn = audiopci_set_reclevel;
1351 		break;
1352 
1353 	case CTL_CD:
1354 		desc.acd_name = AUDIO_CTRL_ID_CD;
1355 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1356 		desc.acd_minvalue = 0;
1357 		desc.acd_maxvalue = 100;
1358 		desc.acd_flags = RECVOL;
1359 		fn = audiopci_set_reclevel;
1360 		break;
1361 
1362 	case CTL_VID:
1363 		desc.acd_name = AUDIO_CTRL_ID_VIDEO;
1364 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1365 		desc.acd_minvalue = 0;
1366 		desc.acd_maxvalue = 100;
1367 		desc.acd_flags = RECVOL;
1368 		fn = audiopci_set_reclevel;
1369 		break;
1370 
1371 	case CTL_PHONE:
1372 		desc.acd_name = AUDIO_CTRL_ID_PHONE;
1373 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1374 		desc.acd_minvalue = 0;
1375 		desc.acd_maxvalue = 100;
1376 		desc.acd_flags = RECVOL;
1377 		fn = audiopci_set_reclevel;
1378 		break;
1379 
1380 	case CTL_RECSRC:
1381 		desc.acd_name = AUDIO_CTRL_ID_RECSRC;
1382 		desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
1383 		desc.acd_minvalue = INSRCS;
1384 		desc.acd_maxvalue = INSRCS;
1385 		desc.acd_flags = RECCTL | 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_recsrc;
1390 		break;
1391 
1392 	case CTL_MONSRC:
1393 		desc.acd_name = AUDIO_CTRL_ID_MONSRC;
1394 		desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
1395 		desc.acd_minvalue = INSRCS;
1396 		desc.acd_maxvalue = INSRCS;
1397 		desc.acd_flags = MONCTL | AUDIO_CTRL_FLAG_MULTI;
1398 		for (int i = 0; audiopci_insrcs[i]; i++) {
1399 			desc.acd_enum[i] = audiopci_insrcs[i];
1400 		}
1401 		fn = audiopci_set_monsrc;
1402 		break;
1403 
1404 	case CTL_MICBOOST:
1405 		desc.acd_name = AUDIO_CTRL_ID_MICBOOST;
1406 		desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN;
1407 		desc.acd_minvalue = 0;
1408 		desc.acd_maxvalue = 100;
1409 		desc.acd_flags = RECCTL;
1410 		fn = audiopci_set_micboost;
1411 		break;
1412 	}
1413 
1414 	pc->val = val;
1415 	pc->ctrl = audio_dev_add_control(dev->adev, &desc,
1416 	    audiopci_get_value, fn, pc);
1417 }
1418 
1419 static int
1420 audiopci_add_controls(audiopci_dev_t *dev)
1421 {
1422 	audiopci_alloc_ctrl(dev, CTL_VOLUME, 75);
1423 	audiopci_alloc_ctrl(dev, CTL_FRONT, ((75) | (75 << 8)));
1424 	audiopci_alloc_ctrl(dev, CTL_MONO, 75);
1425 	audiopci_alloc_ctrl(dev, CTL_MIC, 50);
1426 	audiopci_alloc_ctrl(dev, CTL_LINE, 0);
1427 	audiopci_alloc_ctrl(dev, CTL_CD, 0);
1428 	audiopci_alloc_ctrl(dev, CTL_VID, 0);
1429 	audiopci_alloc_ctrl(dev, CTL_PHONE, 0);
1430 	audiopci_alloc_ctrl(dev, CTL_RECSRC, (1U << INPUT_MIC));
1431 	audiopci_alloc_ctrl(dev, CTL_MONSRC, 0);
1432 	audiopci_alloc_ctrl(dev, CTL_MICBOOST, 1);
1433 
1434 	audiopci_configure_output(dev);
1435 	audiopci_configure_input(dev);
1436 
1437 	return (DDI_SUCCESS);
1438 }
1439 
1440 void
1441 audiopci_del_controls(audiopci_dev_t *dev)
1442 {
1443 	for (int i = 0; i < CTL_NUM; i++) {
1444 		if (dev->controls[i].ctrl) {
1445 			audio_dev_del_control(dev->controls[i].ctrl);
1446 		}
1447 	}
1448 }
1449 
1450 int
1451 audiopci_attach(dev_info_t *dip)
1452 {
1453 	uint16_t pci_command, vendor, device;
1454 	audiopci_dev_t *dev;
1455 	ddi_acc_handle_t pcih;
1456 
1457 	dev = kmem_zalloc(sizeof (*dev), KM_SLEEP);
1458 	dev->dip = dip;
1459 	ddi_set_driver_private(dip, dev);
1460 
1461 	if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) {
1462 		audio_dev_warn(dev->adev, "pci_config_setup failed");
1463 		kmem_free(dev, sizeof (*dev));
1464 		return (DDI_FAILURE);
1465 	}
1466 
1467 	vendor = pci_config_get16(pcih, PCI_CONF_VENID);
1468 	device = pci_config_get16(pcih, PCI_CONF_DEVID);
1469 
1470 	if ((vendor != ENSONIQ_VENDOR_ID && vendor != CREATIVE_VENDOR_ID) ||
1471 	    (device != ENSONIQ_ES1370))
1472 		goto err_exit;
1473 
1474 	dev->devid = device;
1475 
1476 	dev->adev = audio_dev_alloc(dip, 0);
1477 	if (dev->adev == NULL) {
1478 		goto err_exit;
1479 	}
1480 
1481 	audio_dev_set_description(dev->adev, "AudioPCI");
1482 	audio_dev_set_version(dev->adev, "ES1370");
1483 	audio_dev_add_info(dev->adev, "Legacy codec: Asahi Kasei AK4531");
1484 
1485 	/* activate the device */
1486 	pci_command = pci_config_get16(pcih, PCI_CONF_COMM);
1487 	pci_command |= PCI_COMM_ME | PCI_COMM_IO;
1488 	pci_config_put16(pcih, PCI_CONF_COMM, pci_command);
1489 
1490 	/* map registers */
1491 	if (ddi_regs_map_setup(dip, 1, &dev->regs, 0, 0, &acc_attr,
1492 	    &dev->acch) != DDI_SUCCESS) {
1493 		audio_dev_warn(dev->adev, "can't map registers");
1494 		goto err_exit;
1495 	}
1496 
1497 	if (audiopci_setup_interrupts(dev) != DDI_SUCCESS) {
1498 		audio_dev_warn(dev->adev, "can't register interrupts");
1499 		goto err_exit;
1500 	}
1501 
1502 	/* This allocates and configures the engines */
1503 	if (audiopci_init(dev) != DDI_SUCCESS) {
1504 		audio_dev_warn(dev->adev, "can't init device");
1505 		goto err_exit;
1506 	}
1507 
1508 	(void) ddi_intr_enable(dev->ihandle[0]);
1509 
1510 	pci_config_teardown(&pcih);
1511 
1512 	ddi_report_dev(dip);
1513 
1514 	return (DDI_SUCCESS);
1515 
1516 err_exit:
1517 	pci_config_teardown(&pcih);
1518 
1519 	audiopci_destroy(dev);
1520 
1521 	return (DDI_FAILURE);
1522 }
1523 
1524 int
1525 audiopci_detach(audiopci_dev_t *dev)
1526 {
1527 	int tmp;
1528 
1529 	/* first unregister us from the DDI framework, might be busy */
1530 	if (audio_dev_unregister(dev->adev) != DDI_SUCCESS)
1531 		return (DDI_FAILURE);
1532 
1533 	mutex_enter(&dev->mutex);
1534 
1535 	tmp = GET8(dev, CONC_bSERCTL_OFF) &
1536 	    ~(CONC_SERCTL_DACIE | CONC_SERCTL_SYNIE | CONC_SERCTL_ADCIE);
1537 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1538 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1539 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1540 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1541 
1542 	tmp = GET8(dev, CONC_bDEVCTL_OFF) &
1543 	    ~(CONC_DEVCTL_DAC_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_SYN_EN);
1544 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1545 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1546 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1547 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1548 
1549 	dev->enabled = B_FALSE;
1550 
1551 	mutex_exit(&dev->mutex);
1552 
1553 	audiopci_destroy(dev);
1554 
1555 	return (DDI_SUCCESS);
1556 }
1557 
1558 static int
1559 audiopci_resume(audiopci_dev_t *dev)
1560 {
1561 	/* ask framework to reset/relocate engine data */
1562 	for (int i = 0; i <= PORT_MAX; i++) {
1563 		audio_engine_reset(dev->port[i].engine);
1564 	}
1565 
1566 	mutex_enter(&dev->mutex);
1567 	dev->suspended = B_FALSE;
1568 
1569 	/* reinitialize hardware */
1570 	audiopci_init_hw(dev);
1571 
1572 	/* restore mixer settings */
1573 	audiopci_configure_output(dev);
1574 	audiopci_configure_input(dev);
1575 
1576 	/* restart ports */
1577 	for (int i = 0; i < PORT_MAX; i++) {
1578 		audiopci_port_t	*port = &dev->port[i];
1579 		audiopci_init_port(port);
1580 		/* possibly start it up if was going when we suspended */
1581 		if (port->trigger) {
1582 			audiopci_start_port(port);
1583 
1584 			/* signal callbacks on resume */
1585 			if (port->num == PORT_ADC) {
1586 				audio_engine_produce(port->engine);
1587 			} else {
1588 				audio_engine_consume(port->engine);
1589 			}
1590 		}
1591 	}
1592 	mutex_exit(&dev->mutex);
1593 	return (DDI_SUCCESS);
1594 }
1595 
1596 static int
1597 audiopci_suspend(audiopci_dev_t *dev)
1598 {
1599 	/*
1600 	 * Stop all engines/DMA data.
1601 	 */
1602 	mutex_enter(&dev->mutex);
1603 	for (int i = 0; i <= PORT_MAX; i++) {
1604 		audiopci_stop_port(&dev->port[i]);
1605 		audiopci_update_port(&dev->port[i]);
1606 	}
1607 	dev->suspended = B_TRUE;
1608 	dev->enabled = B_FALSE;
1609 	mutex_exit(&dev->mutex);
1610 
1611 	return (DDI_SUCCESS);
1612 }
1613 
1614 static int
1615 audiopci_quiesce(dev_info_t *dip)
1616 {
1617 	audiopci_dev_t	*dev;
1618 	uint8_t		tmp;
1619 
1620 	if ((dev = ddi_get_driver_private(dip)) == NULL) {
1621 		return (DDI_FAILURE);
1622 	}
1623 
1624 	/* This disables all DMA engines and interrupts */
1625 	tmp = GET8(dev, CONC_bSERCTL_OFF) &
1626 	    ~(CONC_SERCTL_DACIE | CONC_SERCTL_SYNIE | CONC_SERCTL_ADCIE);
1627 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1628 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1629 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1630 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1631 
1632 	tmp = GET8(dev, CONC_bDEVCTL_OFF) &
1633 	    ~(CONC_DEVCTL_DAC_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_SYN_EN);
1634 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1635 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1636 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1637 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1638 
1639 	return (DDI_SUCCESS);
1640 }
1641 
1642 
1643 static int
1644 audiopci_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1645 {
1646 	audiopci_dev_t *dev;
1647 
1648 	switch (cmd) {
1649 	case DDI_ATTACH:
1650 		return (audiopci_attach(dip));
1651 
1652 	case DDI_RESUME:
1653 		if ((dev = ddi_get_driver_private(dip)) == NULL) {
1654 			return (DDI_FAILURE);
1655 		}
1656 		return (audiopci_resume(dev));
1657 
1658 	default:
1659 		return (DDI_FAILURE);
1660 	}
1661 }
1662 
1663 static int
1664 audiopci_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1665 {
1666 	audiopci_dev_t *dev;
1667 
1668 	if ((dev = ddi_get_driver_private(dip)) == NULL) {
1669 		return (DDI_FAILURE);
1670 	}
1671 
1672 	switch (cmd) {
1673 	case DDI_DETACH:
1674 		return (audiopci_detach(dev));
1675 
1676 	case DDI_SUSPEND:
1677 		return (audiopci_suspend(dev));
1678 	default:
1679 		return (DDI_FAILURE);
1680 	}
1681 }
1682 
1683 static struct dev_ops audiopci_dev_ops = {
1684 	DEVO_REV,		/* rev */
1685 	0,			/* refcnt */
1686 	NULL,			/* getinfo */
1687 	nulldev,		/* identify */
1688 	nulldev,		/* probe */
1689 	audiopci_ddi_attach,	/* attach */
1690 	audiopci_ddi_detach,	/* detach */
1691 	nodev,			/* reset */
1692 	NULL,			/* cb_ops */
1693 	NULL,			/* bus_ops */
1694 	NULL,			/* power */
1695 	audiopci_quiesce,	/* quiesce */
1696 };
1697 
1698 static struct modldrv audiopci_modldrv = {
1699 	&mod_driverops,			/* drv_modops */
1700 	"Ensoniq 1370 Audio",		/* linkinfo */
1701 	&audiopci_dev_ops,		/* dev_ops */
1702 };
1703 
1704 static struct modlinkage modlinkage = {
1705 	MODREV_1,
1706 	{ &audiopci_modldrv, NULL }
1707 };
1708 
1709 int
1710 _init(void)
1711 {
1712 	int	rv;
1713 
1714 	audio_init_ops(&audiopci_dev_ops, DRVNAME);
1715 	if ((rv = mod_install(&modlinkage)) != 0) {
1716 		audio_fini_ops(&audiopci_dev_ops);
1717 	}
1718 	return (rv);
1719 }
1720 
1721 int
1722 _fini(void)
1723 {
1724 	int	rv;
1725 
1726 	if ((rv = mod_remove(&modlinkage)) == 0) {
1727 		audio_fini_ops(&audiopci_dev_ops);
1728 	}
1729 	return (rv);
1730 }
1731 
1732 int
1733 _info(struct modinfo *modinfop)
1734 {
1735 	return (mod_info(&modlinkage, modinfop));
1736 }
1737