xref: /illumos-gate/usr/src/uts/common/io/audio/drv/audioens/audioens.c (revision 726fad2a65f16c200a03969c29cb5c86c2d427db)
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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 /*
25  * Purpose: Creative/Ensoniq AudioPCI97  driver (ES1371/ES1373)
26  *
27  * This driver is used with the original Ensoniq AudioPCI97 card and many
28  * PCI based Sound Blaster cards by Creative Technologies. For example
29  * Sound Blaster PCI128 and Creative/Ectiva EV1938.
30  */
31 
32 /*
33  * This file is part of Open Sound System
34  *
35  * Copyright (C) 4Front Technologies 1996-2008.
36  *
37  * This software is released under CDDL 1.0 source license.
38  * See the COPYING file included in the main directory of this source
39  * distribution for the license terms and conditions.
40  */
41 
42 #include <sys/audio/audio_driver.h>
43 #include <sys/audio/ac97.h>
44 #include <sys/note.h>
45 #include <sys/pci.h>
46 #include "audioens.h"
47 
48 /*
49  * Set the latency to 32, 64, 96, 128 clocks - some APCI97 devices exhibit
50  * garbled audio in some cases and setting the latency to higer values fixes it
51  * Values: 32, 64, 96, 128 - Default: 64 (or defined by bios)
52  */
53 int audioens_latency = 0;
54 
55 /*
56  * Enable SPDIF port on SoundBlaster 128D or Sound Blaster Digital-4.1 models
57  * Values: 1=Enable 0=Disable Default: 0
58  */
59 int audioens_spdif = 0;
60 
61 /*
62  * Note: Latest devices can support SPDIF with AC3 pass thru.
63  * However, in order to do this, one of the two DMA engines must be
64  * dedicated to this, which would prevent the card from supporting 4
65  * channel audio.  For now we don't bother with the AC3 pass through
66  * mode, and instead just focus on 4 channel support.  In the future,
67  * this could be selectable via a property.
68  */
69 
70 #define	ENSONIQ_VENDOR_ID	0x1274
71 #define	CREATIVE_VENDOR_ID	0x1102
72 #define	ECTIVA_VENDOR_ID	0x1102
73 #define	ENSONIQ_ES1371		0x1371
74 #define	ENSONIQ_ES5880		0x8001
75 #define	ENSONIQ_ES5880A		0x8002
76 #define	ENSONIQ_ES5880B		0x5880
77 #define	ECTIVA_ES1938		0x8938
78 
79 #define	DEFRATE			48000
80 #define	DRVNAME			"audioens"
81 
82 typedef struct audioens_port
83 {
84 	/* Audio parameters */
85 	int			speed;
86 
87 	int			num;
88 #define	PORT_DAC		0
89 #define	PORT_ADC		1
90 #define	PORT_MAX		PORT_ADC
91 
92 	caddr_t			kaddr;
93 	uint32_t		paddr;
94 	ddi_acc_handle_t	acch;
95 	ddi_dma_handle_t	dmah;
96 	int			nchan;
97 	unsigned		nframes;
98 	unsigned		frameno;
99 	uint64_t		count;
100 
101 	struct audioens_dev	*dev;
102 	audio_engine_t	*engine;
103 } audioens_port_t;
104 
105 typedef struct audioens_dev
106 {
107 	audio_dev_t		*osdev;
108 	kmutex_t		mutex;
109 	uint16_t		devid;
110 	uint8_t			revision;
111 	dev_info_t		*dip;
112 
113 	audioens_port_t		port[PORT_MAX + 1];
114 
115 	ac97_t			*ac97;
116 
117 	caddr_t			regs;
118 	ddi_acc_handle_t	acch;
119 } audioens_dev_t;
120 
121 static ddi_device_acc_attr_t acc_attr = {
122 	DDI_DEVICE_ATTR_V0,
123 	DDI_STRUCTURE_LE_ACC,
124 	DDI_STRICTORDER_ACC
125 };
126 
127 static ddi_device_acc_attr_t buf_attr = {
128 	DDI_DEVICE_ATTR_V0,
129 	DDI_NEVERSWAP_ACC,
130 	DDI_STRICTORDER_ACC
131 };
132 
133 /*
134  * The hardware appears to be able to address up to 16-bits worth of longwords,
135  * giving a total address space of 256K.  But we need substantially less.
136  */
137 #define	AUDIOENS_BUF_LEN	(16384)
138 
139 static ddi_dma_attr_t dma_attr = {
140 	DMA_ATTR_VERSION,	/* dma_attr_version */
141 	0x0,			/* dma_attr_addr_lo */
142 	0xffffffffU,		/* dma_attr_addr_hi */
143 	0x3ffff,		/* dma_attr_count_max */
144 	0x8,			/* dma_attr_align */
145 	0x7f,			/* dma_attr_burstsizes */
146 	0x1,			/* dma_attr_minxfer */
147 	0x3ffff,		/* dma_attr_maxxfer */
148 	0x3ffff,		/* dma_attr_seg */
149 	0x1,			/* dma_attr_sgllen */
150 	0x1,			/* dma_attr_granular */
151 	0			/* dma_attr_flags */
152 };
153 
154 #define	GET8(dev, offset)	\
155 	ddi_get8(dev->acch, (uint8_t *)(dev->regs + (offset)))
156 #define	GET16(dev, offset)	\
157 	ddi_get16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)))
158 #define	GET32(dev, offset)	\
159 	ddi_get32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)))
160 #define	PUT8(dev, offset, v)	\
161 	ddi_put8(dev->acch, (uint8_t *)(dev->regs + (offset)), v)
162 #define	PUT16(dev, offset, v)	\
163 	ddi_put16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)), v)
164 #define	PUT32(dev, offset, v)	\
165 	ddi_put32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)), v)
166 
167 #define	CLR8(dev, offset, v)	PUT8(dev, offset, GET8(dev, offset) & ~(v))
168 #define	SET8(dev, offset, v)	PUT8(dev, offset, GET8(dev, offset) | (v))
169 #define	CLR32(dev, offset, v)	PUT32(dev, offset, GET32(dev, offset) & ~(v))
170 #define	SET32(dev, offset, v)	PUT32(dev, offset, GET32(dev, offset) | (v))
171 
172 static void audioens_init_hw(audioens_dev_t *);
173 
174 static uint16_t
175 audioens_rd97(void *dev_, uint8_t wAddr)
176 {
177 	audioens_dev_t *dev = dev_;
178 	int i, dtemp;
179 
180 	mutex_enter(&dev->mutex);
181 	dtemp = GET32(dev, CONC_dCODECCTL_OFF);
182 	/* wait for WIP to go away saving the current state for later */
183 	for (i = 0; i < 0x100UL; ++i) {
184 		dtemp = GET32(dev, CONC_dCODECCTL_OFF);
185 		if ((dtemp & (1UL << 30)) == 0)
186 			break;
187 	}
188 
189 	/* write addr w/data=0 and assert read request ... */
190 	PUT32(dev, CONC_dCODECCTL_OFF, ((int)wAddr << 16) | (1UL << 23));
191 
192 	/* now wait for the data (RDY) */
193 	for (i = 0; i < 0x100UL; ++i) {
194 		dtemp = GET32(dev, CONC_dCODECCTL_OFF);
195 		if (dtemp & (1UL << 31))
196 			break;
197 	}
198 	dtemp = GET32(dev, CONC_dCODECCTL_OFF);
199 	mutex_exit(&dev->mutex);
200 
201 	return (dtemp & 0xffff);
202 }
203 
204 static void
205 audioens_wr97(void *dev_, uint8_t wAddr, uint16_t wData)
206 {
207 	audioens_dev_t *dev = dev_;
208 	int i, dtemp;
209 
210 	mutex_enter(&dev->mutex);
211 	/* wait for WIP to go away */
212 	for (i = 0; i < 0x100UL; ++i) {
213 		dtemp = GET32(dev, CONC_dCODECCTL_OFF);
214 		if ((dtemp & (1UL << 30)) == 0)
215 			break;
216 	}
217 
218 	PUT32(dev, CONC_dCODECCTL_OFF, ((int)wAddr << 16) | wData);
219 
220 	mutex_exit(&dev->mutex);
221 }
222 
223 static unsigned short
224 SRCRegRead(audioens_dev_t *dev, unsigned short reg)
225 {
226 	int i, dtemp;
227 
228 	dtemp = GET32(dev, CONC_dSRCIO_OFF);
229 	/* wait for ready */
230 	for (i = 0; i < SRC_IOPOLL_COUNT; ++i) {
231 		dtemp = GET32(dev, CONC_dSRCIO_OFF);
232 		if ((dtemp & SRC_BUSY) == 0)
233 			break;
234 	}
235 
236 	/* assert a read request */
237 	PUT32(dev, CONC_dSRCIO_OFF, (dtemp & SRC_CTLMASK) | ((int)reg << 25));
238 
239 	/* now wait for the data */
240 	for (i = 0; i < SRC_IOPOLL_COUNT; ++i) {
241 		dtemp = GET32(dev, CONC_dSRCIO_OFF);
242 		if ((dtemp & SRC_BUSY) == 0)
243 			break;
244 	}
245 
246 	return ((unsigned short) dtemp);
247 }
248 
249 static void
250 SRCRegWrite(audioens_dev_t *dev, unsigned short reg, unsigned short val)
251 {
252 	int i, dtemp;
253 	int writeval;
254 
255 	dtemp = GET32(dev, CONC_dSRCIO_OFF);
256 	/* wait for ready */
257 	for (i = 0; i < SRC_IOPOLL_COUNT; ++i) {
258 		dtemp = GET32(dev, CONC_dSRCIO_OFF);
259 		if ((dtemp & SRC_BUSY) == 0)
260 			break;
261 	}
262 
263 	/* assert the write request */
264 	writeval = (dtemp & SRC_CTLMASK) | SRC_WENABLE |
265 	    ((int)reg << 25) | val;
266 	PUT32(dev, CONC_dSRCIO_OFF, writeval);
267 }
268 
269 static void
270 SRCSetRate(audioens_dev_t *dev, unsigned char base, unsigned short rate)
271 {
272 	int i, freq, dtemp;
273 	unsigned short N, truncM, truncStart;
274 
275 	if (base != SRC_ADC_BASE) {
276 		/* freeze the channel */
277 		dtemp = (base == SRC_DAC1_BASE) ?
278 		    SRC_DAC1FREEZE : SRC_DAC2FREEZE;
279 		for (i = 0; i < SRC_IOPOLL_COUNT; ++i) {
280 			if (!(GET32(dev, CONC_dSRCIO_OFF) & SRC_BUSY))
281 				break;
282 		}
283 		PUT32(dev, CONC_dSRCIO_OFF,
284 		    (GET32(dev, CONC_dSRCIO_OFF) & SRC_CTLMASK) | dtemp);
285 
286 		/* calculate new frequency and write it - preserve accum */
287 		freq = ((int)rate << 16) / 3000U;
288 		SRCRegWrite(dev, (unsigned short) base + SRC_INT_REGS_OFF,
289 		    (SRCRegRead(dev, (unsigned short) base + SRC_INT_REGS_OFF)
290 		    & 0x00ffU) | ((unsigned short) (freq >> 6) & 0xfc00));
291 		SRCRegWrite(dev, (unsigned short) base + SRC_VFREQ_FRAC_OFF,
292 		    (unsigned short) freq >> 1);
293 
294 		/* un-freeze the channel */
295 		for (i = 0; i < SRC_IOPOLL_COUNT; ++i)
296 			if (!(GET32(dev, CONC_dSRCIO_OFF) & SRC_BUSY))
297 				break;
298 		PUT32(dev, CONC_dSRCIO_OFF,
299 		    (GET32(dev, CONC_dSRCIO_OFF) & SRC_CTLMASK) & ~dtemp);
300 	} else {
301 		/* derive oversample ratio */
302 		N = rate / 3000U;
303 		if (N == 15 || N == 13 || N == 11 || N == 9)
304 			--N;
305 
306 		/* truncate the filter and write n/trunc_start */
307 		truncM = (21 * N - 1) | 1;
308 		if (rate >= 24000U) {
309 			if (truncM > 239)
310 				truncM = 239;
311 			truncStart = (239 - truncM) >> 1;
312 
313 			SRCRegWrite(dev, base + SRC_TRUNC_N_OFF,
314 			    (truncStart << 9) | (N << 4));
315 		} else {
316 			if (truncM > 119)
317 				truncM = 119;
318 			truncStart = (119 - truncM) >> 1;
319 
320 			SRCRegWrite(dev, base + SRC_TRUNC_N_OFF,
321 			    0x8000U | (truncStart << 9) | (N << 4));
322 		}
323 
324 		/* calculate new frequency and write it - preserve accum */
325 		freq = ((48000UL << 16) / rate) * N;
326 		SRCRegWrite(dev, base + SRC_INT_REGS_OFF,
327 		    (SRCRegRead(dev, (unsigned short) base + SRC_INT_REGS_OFF)
328 		    & 0x00ff) | ((unsigned short) (freq >> 6) & 0xfc00));
329 		SRCRegWrite(dev, base + SRC_VFREQ_FRAC_OFF,
330 		    (unsigned short) freq >> 1);
331 
332 		SRCRegWrite(dev, SRC_ADC_VOL_L, N << 8);
333 		SRCRegWrite(dev, SRC_ADC_VOL_R, N << 8);
334 	}
335 }
336 
337 static void
338 SRCInit(audioens_dev_t *dev)
339 {
340 	int i;
341 
342 	/* Clear all SRC RAM then init - keep SRC disabled until done */
343 	for (i = 0; i < SRC_IOPOLL_COUNT; ++i) {
344 		if (!(GET32(dev, CONC_dSRCIO_OFF) & SRC_BUSY))
345 			break;
346 	}
347 	PUT32(dev, CONC_dSRCIO_OFF, SRC_DISABLE);
348 
349 	for (i = 0; i < 0x80; ++i)
350 		SRCRegWrite(dev, (unsigned short) i, 0U);
351 
352 	SRCRegWrite(dev, SRC_DAC1_BASE + SRC_TRUNC_N_OFF, 16 << 4);
353 	SRCRegWrite(dev, SRC_DAC1_BASE + SRC_INT_REGS_OFF, 16 << 10);
354 	SRCRegWrite(dev, SRC_DAC2_BASE + SRC_TRUNC_N_OFF, 16 << 4);
355 	SRCRegWrite(dev, SRC_DAC2_BASE + SRC_INT_REGS_OFF, 16 << 10);
356 	SRCRegWrite(dev, SRC_DAC1_VOL_L, 1 << 12);
357 	SRCRegWrite(dev, SRC_DAC1_VOL_R, 1 << 12);
358 	SRCRegWrite(dev, SRC_DAC2_VOL_L, 1 << 12);
359 	SRCRegWrite(dev, SRC_DAC2_VOL_R, 1 << 12);
360 	SRCRegWrite(dev, SRC_ADC_VOL_L, 1 << 12);
361 	SRCRegWrite(dev, SRC_ADC_VOL_R, 1 << 12);
362 
363 	/* default some rates */
364 	SRCSetRate(dev, SRC_DAC1_BASE, 48000);
365 	SRCSetRate(dev, SRC_DAC2_BASE, 48000);
366 	SRCSetRate(dev, SRC_ADC_BASE, 48000);
367 
368 	/* now enable the whole deal */
369 	for (i = 0; i < SRC_IOPOLL_COUNT; ++i) {
370 		if (!(GET32(dev, CONC_dSRCIO_OFF) & SRC_BUSY))
371 			break;
372 	}
373 	PUT32(dev, CONC_dSRCIO_OFF, 0);
374 }
375 
376 static void
377 audioens_writemem(audioens_dev_t *dev, uint32_t page, uint32_t offs,
378     uint32_t data)
379 {
380 	/* Select memory page */
381 	PUT32(dev, CONC_bMEMPAGE_OFF, page);
382 	PUT32(dev, offs, data);
383 }
384 
385 static uint32_t
386 audioens_readmem(audioens_dev_t *dev, uint32_t page, uint32_t offs)
387 {
388 	PUT32(dev, CONC_bMEMPAGE_OFF, page);	/* Select memory page */
389 	return (GET32(dev, offs));
390 }
391 
392 /*
393  * Audio routines
394  */
395 static int
396 audioens_format(void *arg)
397 {
398 	_NOTE(ARGUNUSED(arg));
399 
400 	/* hardware can also do AUDIO_FORMAT_U8, but no need for it */
401 	return (AUDIO_FORMAT_S16_LE);
402 }
403 
404 static int
405 audioens_channels(void *arg)
406 {
407 	audioens_port_t *port = arg;
408 
409 	return (port->nchan);
410 }
411 
412 static int
413 audioens_rate(void *arg)
414 {
415 	audioens_port_t *port = arg;
416 
417 	return (port->speed);
418 }
419 
420 static int
421 audioens_open(void *arg, int flag, unsigned *nframes, caddr_t *bufp)
422 {
423 	audioens_port_t	*port = arg;
424 	audioens_dev_t	*dev = port->dev;
425 
426 	_NOTE(ARGUNUSED(flag));
427 
428 	mutex_enter(&dev->mutex);
429 
430 	port->nframes = AUDIOENS_BUF_LEN / (port->nchan * sizeof (int16_t));
431 	port->count = 0;
432 
433 	*nframes = port->nframes;
434 	*bufp = port->kaddr;
435 	mutex_exit(&dev->mutex);
436 
437 	return (0);
438 }
439 
440 static int
441 audioens_start(void *arg)
442 {
443 	audioens_port_t *port = arg;
444 	audioens_dev_t *dev = port->dev;
445 	uint32_t tmp;
446 
447 	mutex_enter(&dev->mutex);
448 
449 	switch (port->num) {
450 	case PORT_DAC:
451 		/* Set physical address of the DMA buffer */
452 		audioens_writemem(dev, CONC_DAC1CTL_PAGE, CONC_dDAC1PADDR_OFF,
453 		    port->paddr);
454 		audioens_writemem(dev, CONC_DAC2CTL_PAGE, CONC_dDAC2PADDR_OFF,
455 		    port->paddr + (port->nframes * sizeof (int16_t) * 2));
456 
457 		/* Set DAC rate */
458 		SRCSetRate(dev, SRC_DAC1_BASE, port->speed);
459 		SRCSetRate(dev, SRC_DAC2_BASE, port->speed);
460 
461 		/* Configure the channel setup - SPDIF only uses front */
462 		tmp = GET32(dev, CONC_dSTATUS_OFF);
463 		tmp &= ~(CONC_STATUS_SPKR_MASK | CONC_STATUS_SPDIF_MASK);
464 		tmp |= CONC_STATUS_SPKR_4CH | CONC_STATUS_SPDIF_P1;
465 		PUT32(dev, CONC_dSTATUS_OFF, tmp);
466 
467 		/* Set format */
468 		PUT8(dev, CONC_bSKIPC_OFF, 0x10);
469 		SET8(dev, CONC_bSERFMT_OFF,
470 		    CONC_PCM_DAC1_16BIT | CONC_PCM_DAC2_16BIT |
471 		    CONC_PCM_DAC1_STEREO | CONC_PCM_DAC2_STEREO);
472 
473 		/* Set the frame count */
474 		audioens_writemem(dev, CONC_DAC1CTL_PAGE, CONC_wDAC1FC_OFF,
475 		    port->nframes - 1);
476 		audioens_writemem(dev, CONC_DAC2CTL_PAGE, CONC_wDAC2FC_OFF,
477 		    port->nframes - 1);
478 
479 		/* Set # of frames between interrupts */
480 		PUT16(dev, CONC_wDAC1IC_OFF, port->nframes - 1);
481 		PUT16(dev, CONC_wDAC2IC_OFF, port->nframes - 1);
482 
483 		SET8(dev, CONC_bDEVCTL_OFF,
484 		    CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_DAC1_EN);
485 
486 		break;
487 
488 	case PORT_ADC:
489 		/* Set physical address of the DMA buffer */
490 		audioens_writemem(dev, CONC_ADCCTL_PAGE, CONC_dADCPADDR_OFF,
491 		    port->paddr);
492 
493 		/* Set ADC rate */
494 		SRCSetRate(dev, SRC_ADC_BASE, port->speed);
495 
496 		/* Set format - for input we only support 16 bit input */
497 		tmp = GET8(dev, CONC_bSERFMT_OFF);
498 		tmp |= CONC_PCM_ADC_16BIT;
499 		tmp |= CONC_PCM_ADC_STEREO;
500 
501 		PUT8(dev, CONC_bSKIPC_OFF, 0x10);
502 
503 		PUT8(dev, CONC_bSERFMT_OFF, tmp);
504 
505 		/* Set the frame count */
506 		audioens_writemem(dev, CONC_ADCCTL_PAGE, CONC_wADCFC_OFF,
507 		    port->nframes - 1);
508 
509 		/* Set # of frames between interrupts */
510 		PUT16(dev, CONC_wADCIC_OFF, port->nframes - 1);
511 
512 		SET8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_ADC_EN);
513 		break;
514 	}
515 
516 	port->frameno = 0;
517 	mutex_exit(&dev->mutex);
518 
519 	return (0);
520 }
521 
522 static void
523 audioens_stop(void *arg)
524 {
525 	audioens_port_t *port = arg;
526 	audioens_dev_t *dev = port->dev;
527 
528 	mutex_enter(&dev->mutex);
529 	switch (port->num) {
530 	case PORT_DAC:
531 		CLR8(dev, CONC_bDEVCTL_OFF,
532 		    CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_DAC1_EN);
533 		break;
534 	case PORT_ADC:
535 		CLR8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_ADC_EN);
536 		break;
537 	}
538 	mutex_exit(&dev->mutex);
539 }
540 
541 static uint64_t
542 audioens_count(void *arg)
543 {
544 	audioens_port_t *port = arg;
545 	audioens_dev_t *dev = port->dev;
546 	uint64_t val;
547 	uint32_t page, offs;
548 	int frameno, n;
549 
550 	switch (port->num) {
551 	case PORT_DAC:
552 		page = CONC_DAC1CTL_PAGE;
553 		offs = CONC_wDAC1FC_OFF;
554 		break;
555 
556 	case PORT_ADC:
557 		page = CONC_ADCCTL_PAGE;
558 		offs = CONC_wADCFC_OFF;
559 		break;
560 	}
561 
562 	mutex_enter(&dev->mutex);
563 	/*
564 	 * Note that the current frame counter is in the high nybble.
565 	 */
566 	frameno = audioens_readmem(port->dev, page, offs) >> 16;
567 	n = frameno >= port->frameno ?
568 	    frameno - port->frameno :
569 	    frameno + port->nframes - port->frameno;
570 	port->frameno = frameno;
571 	port->count += n;
572 
573 	val = port->count;
574 	mutex_exit(&dev->mutex);
575 
576 	return (val);
577 }
578 
579 static void
580 audioens_close(void *arg)
581 {
582 	_NOTE(ARGUNUSED(arg));
583 }
584 
585 static void
586 audioens_sync(void *arg, unsigned nframes)
587 {
588 	audioens_port_t *port = arg;
589 
590 	_NOTE(ARGUNUSED(nframes));
591 
592 	if (port->num == PORT_ADC) {
593 		(void) ddi_dma_sync(port->dmah, 0, 0, DDI_DMA_SYNC_FORKERNEL);
594 	} else {
595 		(void) ddi_dma_sync(port->dmah, 0, 0, DDI_DMA_SYNC_FORDEV);
596 	}
597 }
598 
599 static void
600 audioens_chinfo(void *arg, int chan, unsigned *offset, unsigned *incr)
601 {
602 	audioens_port_t *port = arg;
603 
604 	if ((port->num == PORT_DAC) && (chan >= 2)) {
605 		*offset = (port->nframes * 2) + (chan % 2);
606 		*incr = 2;
607 	} else {
608 		*offset = chan;
609 		*incr = 2;
610 	}
611 }
612 
613 audio_engine_ops_t audioens_engine_ops = {
614 	AUDIO_ENGINE_VERSION,		/* version number */
615 	audioens_open,
616 	audioens_close,
617 	audioens_start,
618 	audioens_stop,
619 	audioens_count,
620 	audioens_format,
621 	audioens_channels,
622 	audioens_rate,
623 	audioens_sync,
624 	NULL,
625 	audioens_chinfo,
626 	NULL,
627 };
628 
629 void
630 audioens_init_hw(audioens_dev_t *dev)
631 {
632 	int tmp;
633 
634 	if ((dev->devid == ENSONIQ_ES5880) ||
635 	    (dev->devid == ENSONIQ_ES5880A) ||
636 	    (dev->devid == ENSONIQ_ES5880B) ||
637 	    (dev->devid == 0x1371 && dev->revision == 7) ||
638 	    (dev->devid == 0x1371 && dev->revision >= 9)) {
639 
640 		/* Have a ES5880 so enable the codec manually */
641 		tmp = GET8(dev, CONC_bINTSUMM_OFF) & 0xff;
642 		tmp |= 0x20;
643 		PUT8(dev, CONC_bINTSUMM_OFF, tmp);
644 		for (int i = 0; i < 2000; i++)
645 			drv_usecwait(10);
646 	}
647 
648 	SRCInit(dev);
649 
650 	/*
651 	 * Turn on CODEC (UART and joystick left disabled)
652 	 */
653 	tmp = GET32(dev, CONC_bDEVCTL_OFF) & 0xff;
654 	tmp &= ~(CONC_DEVCTL_PCICLK_DS | CONC_DEVCTL_XTALCLK_DS);
655 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
656 	PUT8(dev, CONC_bUARTCSTAT_OFF, 0x00);
657 
658 	/* Perform AC97 codec warm reset */
659 	tmp = GET8(dev, CONC_bMISCCTL_OFF) & 0xff;
660 	PUT8(dev, CONC_bMISCCTL_OFF, tmp | CONC_MISCCTL_SYNC_RES);
661 	drv_usecwait(200);
662 	PUT8(dev, CONC_bMISCCTL_OFF, tmp);
663 	drv_usecwait(200);
664 
665 	if (dev->revision >= 4) {
666 		/* XXX: enable SPDIF - PCM only for now */
667 		if (audioens_spdif) {
668 			/* enable SPDIF */
669 			PUT32(dev, 0x04, GET32(dev, 0x04) | (1 << 18));
670 			/* SPDIF out = data from DAC */
671 			PUT32(dev, 0x00, GET32(dev, 0x00) | (1 << 26));
672 			CLR32(dev, CONC_dSPDIF_OFF, CONC_SPDIF_AC3);
673 
674 		} else {
675 			/* disable spdif out */
676 			PUT32(dev, 0x04, GET32(dev, 0x04) & ~(1 << 18));
677 			PUT32(dev, 0x00, GET32(dev, 0x00) & ~(1 << 26));
678 		}
679 
680 		/* we want to run each channel independently */
681 		CLR32(dev, CONC_dSTATUS_OFF, CONC_STATUS_ECHO);
682 	}
683 }
684 
685 static int
686 audioens_init(audioens_dev_t *dev)
687 {
688 
689 	audioens_init_hw(dev);
690 
691 	/*
692 	 * On this hardware, we want to disable the internal speaker by
693 	 * default, if it exists.  (We don't have a speakerphone on any
694 	 * of these cards, and no SPARC hardware uses it either!)
695 	 */
696 	(void) ddi_prop_update_int(DDI_DEV_T_NONE, dev->dip, AC97_PROP_SPEAKER,
697 	    0);
698 
699 	/*
700 	 * Init mixer
701 	 */
702 
703 	dev->ac97 = ac97_alloc(dev->dip, audioens_rd97, audioens_wr97, dev);
704 	if (dev->ac97 == NULL)
705 		return (DDI_FAILURE);
706 
707 	if (ac97_init(dev->ac97, dev->osdev) != 0) {
708 		return (DDI_FAILURE);
709 	}
710 
711 	for (int i = 0; i <= PORT_MAX; i++) {
712 		audioens_port_t *port;
713 		unsigned caps;
714 		unsigned dmaflags;
715 		size_t rlen;
716 		ddi_dma_cookie_t c;
717 		unsigned ccnt;
718 
719 		port = &dev->port[i];
720 		port->dev = dev;
721 
722 		switch (i) {
723 		case PORT_DAC:
724 			port->nchan = 4;
725 			port->speed = 48000;
726 			caps = ENGINE_OUTPUT_CAP;
727 			dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
728 			break;
729 
730 		case PORT_ADC:
731 			port->nchan = 2;
732 			port->speed = 48000;
733 			caps = ENGINE_INPUT_CAP;
734 			dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT;
735 			break;
736 		}
737 
738 		port->num = i;
739 
740 		/*
741 		 * Allocate DMA resources.
742 		 */
743 
744 		if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_SLEEP,
745 		    NULL, &port->dmah) != DDI_SUCCESS) {
746 			audio_dev_warn(dev->osdev,
747 			    "port %d: dma handle allocation failed", i);
748 			return (DDI_FAILURE);
749 		}
750 		if (ddi_dma_mem_alloc(port->dmah, AUDIOENS_BUF_LEN, &buf_attr,
751 		    DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &port->kaddr,
752 		    &rlen, &port->acch) != DDI_SUCCESS) {
753 			audio_dev_warn(dev->osdev,
754 			    "port %d: dma memory allocation failed", i);
755 			return (DDI_FAILURE);
756 		}
757 		/* ensure that the buffer is zeroed out properly */
758 		bzero(port->kaddr, rlen);
759 		if (ddi_dma_addr_bind_handle(port->dmah, NULL, port->kaddr,
760 		    AUDIOENS_BUF_LEN, dmaflags, DDI_DMA_SLEEP, NULL,
761 		    &c, &ccnt) != DDI_DMA_MAPPED) {
762 			audio_dev_warn(dev->osdev,
763 			    "port %d: dma binding failed", i);
764 			return (DDI_FAILURE);
765 		}
766 		port->paddr = c.dmac_address;
767 
768 		/*
769 		 * Allocate and configure audio engine.
770 		 */
771 		port->engine = audio_engine_alloc(&audioens_engine_ops, caps);
772 		if (port->engine == NULL) {
773 			audio_dev_warn(dev->osdev,
774 			    "port %d: audio_engine_alloc failed", i);
775 			return (DDI_FAILURE);
776 		}
777 
778 		audio_engine_set_private(port->engine, port);
779 		audio_dev_add_engine(dev->osdev, port->engine);
780 	}
781 
782 	/*
783 	 * Set up kstats for interrupt reporting.
784 	 */
785 	if (audio_dev_register(dev->osdev) != DDI_SUCCESS) {
786 		audio_dev_warn(dev->osdev,
787 		    "unable to register with audio framework");
788 		return (DDI_FAILURE);
789 	}
790 
791 	return (DDI_SUCCESS);
792 }
793 
794 void
795 audioens_destroy(audioens_dev_t *dev)
796 {
797 	int	i;
798 
799 	mutex_destroy(&dev->mutex);
800 
801 	/* free up ports, including DMA resources for ports */
802 	for (i = 0; i <= PORT_MAX; i++) {
803 		audioens_port_t	*port = &dev->port[i];
804 
805 		if (port->paddr != 0)
806 			(void) ddi_dma_unbind_handle(port->dmah);
807 		if (port->acch != NULL)
808 			ddi_dma_mem_free(&port->acch);
809 		if (port->dmah != NULL)
810 			ddi_dma_free_handle(&port->dmah);
811 
812 		if (port->engine != NULL) {
813 			audio_dev_remove_engine(dev->osdev, port->engine);
814 			audio_engine_free(port->engine);
815 		}
816 	}
817 
818 	if (dev->acch != NULL) {
819 		ddi_regs_map_free(&dev->acch);
820 	}
821 
822 	if (dev->ac97) {
823 		ac97_free(dev->ac97);
824 	}
825 
826 	if (dev->osdev != NULL) {
827 		audio_dev_free(dev->osdev);
828 	}
829 
830 	kmem_free(dev, sizeof (*dev));
831 }
832 
833 int
834 audioens_attach(dev_info_t *dip)
835 {
836 	uint16_t pci_command, vendor, device;
837 	uint8_t revision;
838 	audioens_dev_t *dev;
839 	ddi_acc_handle_t pcih;
840 	const char *chip_name;
841 	const char *chip_vers;
842 
843 	dev = kmem_zalloc(sizeof (*dev), KM_SLEEP);
844 	dev->dip = dip;
845 	ddi_set_driver_private(dip, dev);
846 	mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, NULL);
847 
848 	if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) {
849 		audio_dev_warn(dev->osdev, "pci_config_setup failed");
850 		mutex_destroy(&dev->mutex);
851 		kmem_free(dev, sizeof (*dev));
852 		return (DDI_FAILURE);
853 	}
854 
855 	vendor = pci_config_get16(pcih, PCI_CONF_VENID);
856 	device = pci_config_get16(pcih, PCI_CONF_DEVID);
857 	revision = pci_config_get8(pcih, PCI_CONF_REVID);
858 
859 	if ((vendor != ENSONIQ_VENDOR_ID && vendor != CREATIVE_VENDOR_ID) ||
860 	    (device != ENSONIQ_ES1371 && device != ENSONIQ_ES5880 &&
861 	    device != ENSONIQ_ES5880A && device != ECTIVA_ES1938 &&
862 	    device != ENSONIQ_ES5880B))
863 		goto err_exit;
864 
865 	chip_name = "AudioPCI97";
866 	chip_vers = "unknown";
867 
868 	switch (device) {
869 	case ENSONIQ_ES1371:
870 		chip_name = "AudioPCI97";
871 		switch (revision) {
872 		case 0x02:
873 		case 0x09:
874 		default:
875 			chip_vers = "ES1371";
876 			break;
877 		case 0x04:
878 		case 0x06:
879 		case 0x08:
880 			chip_vers = "ES1373";
881 			break;
882 		case 0x07:
883 			chip_vers = "ES5880";
884 			break;
885 		}
886 		break;
887 
888 	case ENSONIQ_ES5880:
889 		chip_name = "SB PCI128";
890 		chip_vers = "ES5880";
891 		break;
892 	case ENSONIQ_ES5880A:
893 		chip_name = "SB PCI128";
894 		chip_vers = "ES5880A";
895 		break;
896 	case ENSONIQ_ES5880B:
897 		chip_name = "SB PCI128";
898 		chip_vers = "ES5880B";
899 		break;
900 
901 	case ECTIVA_ES1938:
902 		chip_name = "AudioPCI";
903 		chip_vers = "ES1938";
904 		break;
905 	}
906 
907 	dev->revision = revision;
908 	dev->devid = device;
909 
910 	dev->osdev = audio_dev_alloc(dip, 0);
911 	if (dev->osdev == NULL) {
912 		goto err_exit;
913 	}
914 
915 	audio_dev_set_description(dev->osdev, chip_name);
916 	audio_dev_set_version(dev->osdev, chip_vers);
917 
918 	/* set the PCI latency */
919 	if ((audioens_latency == 32) || (audioens_latency == 64) ||
920 	    (audioens_latency == 96))
921 		pci_config_put8(pcih, PCI_CONF_LATENCY_TIMER,
922 		    audioens_latency);
923 
924 	/* activate the device */
925 	pci_command = pci_config_get16(pcih, PCI_CONF_COMM);
926 	pci_command |= PCI_COMM_ME | PCI_COMM_IO;
927 	pci_config_put16(pcih, PCI_CONF_COMM, pci_command);
928 
929 	/* map registers */
930 	if (ddi_regs_map_setup(dip, 1, &dev->regs, 0, 0, &acc_attr,
931 	    &dev->acch) != DDI_SUCCESS) {
932 		audio_dev_warn(dev->osdev, "can't map registers");
933 		goto err_exit;
934 	}
935 
936 	/* This allocates and configures the engines */
937 	if (audioens_init(dev) != DDI_SUCCESS) {
938 		audio_dev_warn(dev->osdev, "can't init device");
939 		goto err_exit;
940 	}
941 
942 	pci_config_teardown(&pcih);
943 
944 	ddi_report_dev(dip);
945 
946 	return (DDI_SUCCESS);
947 
948 err_exit:
949 	pci_config_teardown(&pcih);
950 
951 	audioens_destroy(dev);
952 
953 	return (DDI_FAILURE);
954 }
955 
956 int
957 audioens_detach(audioens_dev_t *dev)
958 {
959 	int tmp;
960 
961 	/* first unregister us from the DDI framework, might be busy */
962 	if (audio_dev_unregister(dev->osdev) != DDI_SUCCESS)
963 		return (DDI_FAILURE);
964 
965 	mutex_enter(&dev->mutex);
966 
967 	tmp = GET8(dev, CONC_bSERCTL_OFF) &
968 	    ~(CONC_SERCTL_DAC2IE | CONC_SERCTL_DAC1IE | CONC_SERCTL_ADCIE);
969 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
970 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
971 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
972 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
973 
974 	tmp = GET8(dev, CONC_bDEVCTL_OFF) &
975 	    ~(CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_DAC1_EN);
976 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
977 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
978 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
979 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
980 
981 	mutex_exit(&dev->mutex);
982 
983 	audioens_destroy(dev);
984 
985 	return (DDI_SUCCESS);
986 }
987 
988 static int
989 audioens_resume(audioens_dev_t *dev)
990 {
991 	/* reinitialize hardware */
992 	audioens_init_hw(dev);
993 
994 	/* restore AC97 state */
995 	ac97_reset(dev->ac97);
996 
997 	audio_dev_resume(dev->osdev);
998 
999 	return (DDI_SUCCESS);
1000 }
1001 
1002 static int
1003 audioens_suspend(audioens_dev_t *dev)
1004 {
1005 	audio_dev_suspend(dev->osdev);
1006 
1007 	return (DDI_SUCCESS);
1008 }
1009 
1010 static int
1011 audioens_quiesce(dev_info_t *dip)
1012 {
1013 	audioens_dev_t	*dev;
1014 	uint8_t		tmp;
1015 
1016 	if ((dev = ddi_get_driver_private(dip)) == NULL) {
1017 		return (DDI_FAILURE);
1018 	}
1019 
1020 	/* This disables all DMA engines and interrupts */
1021 	tmp = GET8(dev, CONC_bSERCTL_OFF) &
1022 	    ~(CONC_SERCTL_DAC2IE | CONC_SERCTL_DAC1IE | CONC_SERCTL_ADCIE);
1023 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1024 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1025 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1026 	PUT8(dev, CONC_bSERCTL_OFF, tmp);
1027 
1028 	tmp = GET8(dev, CONC_bDEVCTL_OFF) &
1029 	    ~(CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_DAC1_EN);
1030 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1031 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1032 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1033 	PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1034 
1035 	return (DDI_SUCCESS);
1036 }
1037 
1038 
1039 static int
1040 audioens_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1041 {
1042 	audioens_dev_t *dev;
1043 
1044 	switch (cmd) {
1045 	case DDI_ATTACH:
1046 		return (audioens_attach(dip));
1047 
1048 	case DDI_RESUME:
1049 		if ((dev = ddi_get_driver_private(dip)) == NULL) {
1050 			return (DDI_FAILURE);
1051 		}
1052 		return (audioens_resume(dev));
1053 
1054 	default:
1055 		return (DDI_FAILURE);
1056 	}
1057 }
1058 
1059 static int
1060 audioens_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1061 {
1062 	audioens_dev_t *dev;
1063 
1064 	if ((dev = ddi_get_driver_private(dip)) == NULL) {
1065 		return (DDI_FAILURE);
1066 	}
1067 
1068 	switch (cmd) {
1069 	case DDI_DETACH:
1070 		return (audioens_detach(dev));
1071 
1072 	case DDI_SUSPEND:
1073 		return (audioens_suspend(dev));
1074 	default:
1075 		return (DDI_FAILURE);
1076 	}
1077 }
1078 
1079 static int audioens_ddi_attach(dev_info_t *, ddi_attach_cmd_t);
1080 static int audioens_ddi_detach(dev_info_t *, ddi_detach_cmd_t);
1081 
1082 static struct dev_ops audioens_dev_ops = {
1083 	DEVO_REV,		/* rev */
1084 	0,			/* refcnt */
1085 	NULL,			/* getinfo */
1086 	nulldev,		/* identify */
1087 	nulldev,		/* probe */
1088 	audioens_ddi_attach,	/* attach */
1089 	audioens_ddi_detach,	/* detach */
1090 	nodev,			/* reset */
1091 	NULL,			/* cb_ops */
1092 	NULL,			/* bus_ops */
1093 	NULL,			/* power */
1094 	audioens_quiesce,	/* quiesce */
1095 };
1096 
1097 static struct modldrv audioens_modldrv = {
1098 	&mod_driverops,			/* drv_modops */
1099 	"Ensoniq 1371/1373 Audio",	/* linkinfo */
1100 	&audioens_dev_ops,		/* dev_ops */
1101 };
1102 
1103 static struct modlinkage modlinkage = {
1104 	MODREV_1,
1105 	{ &audioens_modldrv, NULL }
1106 };
1107 
1108 int
1109 _init(void)
1110 {
1111 	int	rv;
1112 
1113 	audio_init_ops(&audioens_dev_ops, DRVNAME);
1114 	if ((rv = mod_install(&modlinkage)) != 0) {
1115 		audio_fini_ops(&audioens_dev_ops);
1116 	}
1117 	return (rv);
1118 }
1119 
1120 int
1121 _fini(void)
1122 {
1123 	int	rv;
1124 
1125 	if ((rv = mod_remove(&modlinkage)) == 0) {
1126 		audio_fini_ops(&audioens_dev_ops);
1127 	}
1128 	return (rv);
1129 }
1130 
1131 int
1132 _info(struct modinfo *modinfop)
1133 {
1134 	return (mod_info(&modlinkage, modinfop));
1135 }
1136