audiopci.c revision 9484:fbd5ddc28e96
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
66static 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
75typedef 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
103typedef 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
118typedef 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
127typedef 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
160static ddi_device_acc_attr_t acc_attr = {
161	DDI_DEVICE_ATTR_V0,
162	DDI_STRUCTURE_LE_ACC,
163	DDI_STRICTORDER_ACC
164};
165
166static 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
184static 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
219static void audiopci_init_hw(audiopci_dev_t *);
220static void audiopci_init_port(audiopci_port_t *);
221static void audiopci_start_port(audiopci_port_t *);
222static void audiopci_stop_port(audiopci_port_t *);
223static void audiopci_update_port(audiopci_port_t *);
224static uint16_t audiopci_dac_rate(int);
225static int audiopci_add_controls(audiopci_dev_t *);
226static void audiopci_del_controls(audiopci_dev_t *);
227static void audiopci_ak_write(audiopci_dev_t *, uint16_t, uint8_t);
228
229static int
230audiopci_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
240static void
241audiopci_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
250static void
251audiopci_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
271static void
272audiopci_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
280static uint32_t
281audiopci_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
287static uint_t
288audiopci_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
396static int
397audiopci_format(void *arg)
398{
399	_NOTE(ARGUNUSED(arg));
400	return (AUDIO_FORMAT_S16_LE);
401}
402
403static int
404audiopci_channels(void *arg)
405{
406	_NOTE(ARGUNUSED(arg));
407	return (2);
408}
409
410static int
411audiopci_rate(void *arg)
412{
413	audiopci_port_t	*port = arg;
414
415	return (port->speed);
416}
417
418static void
419audiopci_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
509static int
510audiopci_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
554static void
555audiopci_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
577static void
578audiopci_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
600static int
601audiopci_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
616static void
617audiopci_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
630static void
631audiopci_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
664static uint64_t
665audiopci_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
680static void
681audiopci_close(void *arg)
682{
683	audiopci_port_t *port = arg;
684
685	audiopci_stop(port);
686}
687
688static void
689audiopci_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
702static size_t
703audiopci_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
715audio_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
730static uint16_t
731audiopci_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
749void
750audiopci_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
816static int
817audiopci_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
930int
931audiopci_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
963void
964audiopci_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
1009static void
1010audiopci_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
1033static void
1034audiopci_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
1045static void
1046audiopci_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
1057static int
1058audiopci_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
1069static void
1070audiopci_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
1105static void
1106audiopci_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
1159static int
1160audiopci_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
1181static int
1182audiopci_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
1194static int
1195audiopci_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
1210static int
1211audiopci_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
1226static int
1227audiopci_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
1246static int
1247audiopci_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
1268static int
1269audiopci_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
1294static void
1295audiopci_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
1419static int
1420audiopci_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
1440void
1441audiopci_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
1450int
1451audiopci_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
1516err_exit:
1517	pci_config_teardown(&pcih);
1518
1519	audiopci_destroy(dev);
1520
1521	return (DDI_FAILURE);
1522}
1523
1524int
1525audiopci_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
1558static int
1559audiopci_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
1596static int
1597audiopci_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
1614static int
1615audiopci_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
1643static int
1644audiopci_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
1663static int
1664audiopci_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
1683static 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
1698static struct modldrv audiopci_modldrv = {
1699	&mod_driverops,			/* drv_modops */
1700	"Ensoniq 1370 Audio",		/* linkinfo */
1701	&audiopci_dev_ops,		/* dev_ops */
1702};
1703
1704static struct modlinkage modlinkage = {
1705	MODREV_1,
1706	{ &audiopci_modldrv, NULL }
1707};
1708
1709int
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
1721int
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
1732int
1733_info(struct modinfo *modinfop)
1734{
1735	return (mod_info(&modlinkage, modinfop));
1736}
1737