xref: /illumos-gate/usr/src/uts/common/io/audio/drv/audiols/audiols.c (revision 22a84b8d79248a611e4ba663a268d3c4bed054ac)
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 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * Purpose: Driver for the Creative Audigy LS sound card
29  */
30 /*
31  *
32  * Copyright (C) 4Front Technologies 1996-2009.
33  */
34 
35 #include <sys/types.h>
36 #include <sys/modctl.h>
37 #include <sys/kmem.h>
38 #include <sys/conf.h>
39 #include <sys/ddi.h>
40 #include <sys/sunddi.h>
41 #include <sys/pci.h>
42 #include <sys/note.h>
43 #include <sys/audio/audio_driver.h>
44 #include <sys/audio/ac97.h>
45 
46 #include "audiols.h"
47 
48 static struct ddi_device_acc_attr dev_attr = {
49 	DDI_DEVICE_ATTR_V0,
50 	DDI_STRUCTURE_LE_ACC,
51 	DDI_STRICTORDER_ACC
52 };
53 
54 static struct ddi_device_acc_attr buf_attr = {
55 	DDI_DEVICE_ATTR_V0,
56 	DDI_NEVERSWAP_ACC,
57 	DDI_STRICTORDER_ACC
58 };
59 
60 static ddi_dma_attr_t dma_attr_buf = {
61 	DMA_ATTR_V0,		/* version number */
62 	0x00000000,		/* low DMA address range */
63 	0xffffffff,		/* high DMA address range */
64 	0x000fffff,		/* DMA counter (16 bits only in Audigy LS) */
65 	4,			/* DMA address alignment */
66 	0x3c,			/* DMA burstsizes */
67 	4,			/* min effective DMA size */
68 	0xffffffff,		/* max DMA xfer size */
69 	0xffffffff,		/* segment boundary */
70 	1,			/* s/g length */
71 	4,			/* granularity of device */
72 	0			/* Bus specific DMA flags */
73 };
74 
75 static int audigyls_attach(dev_info_t *);
76 static int audigyls_resume(dev_info_t *);
77 static int audigyls_detach(audigyls_dev_t *);
78 static int audigyls_suspend(audigyls_dev_t *);
79 
80 static int audigyls_open(void *, int, unsigned *, unsigned *, caddr_t *);
81 static void audigyls_close(void *);
82 static int audigyls_start(void *);
83 static void audigyls_stop(void *);
84 static int audigyls_format(void *);
85 static int audigyls_channels(void *);
86 static int audigyls_rate(void *);
87 static uint64_t audigyls_count(void *);
88 static void audigyls_sync(void *, unsigned);
89 static size_t audigyls_qlen(void *);
90 static void audigyls_chinfo(void *, int, unsigned *, unsigned *);
91 
92 
93 static uint16_t audigyls_read_ac97(void *, uint8_t);
94 static void audigyls_write_ac97(void *, uint8_t, uint16_t);
95 static int audigyls_alloc_port(audigyls_dev_t *, int);
96 static void audigyls_start_port(audigyls_port_t *);
97 static void audigyls_stop_port(audigyls_port_t *);
98 static void audigyls_update_port(audigyls_port_t *);
99 static void audigyls_reset_port(audigyls_port_t *);
100 static void audigyls_destroy(audigyls_dev_t *);
101 static int audigyls_setup_intrs(audigyls_dev_t *);
102 static void audigyls_hwinit(audigyls_dev_t *);
103 static uint_t audigyls_intr(caddr_t, caddr_t);
104 static void audigyls_configure_mixer(audigyls_dev_t *dev);
105 
106 static audio_engine_ops_t audigyls_engine_ops = {
107 	AUDIO_ENGINE_VERSION,
108 	audigyls_open,
109 	audigyls_close,
110 	audigyls_start,
111 	audigyls_stop,
112 	audigyls_count,
113 	audigyls_format,
114 	audigyls_channels,
115 	audigyls_rate,
116 	audigyls_sync,
117 	audigyls_qlen,
118 	audigyls_chinfo
119 };
120 
121 /*
122  * Audigy LS uses AC'97 strictly for the recording side of things.
123  * While the chip can supposedly route output to AC'97 for playback,
124  * the PCI devices use a separate I2S DAC instead.  As a result we
125  * need to suppress controls that the AC'97 codec registers.
126  *
127  * Furthermore, even then the AC'97 codec offers inputs that we just
128  * aren't interested in.
129  */
130 const char *audigyls_remove_ac97[] = {
131 	AUDIO_CTRL_ID_VOLUME,
132 	AUDIO_CTRL_ID_LINEOUT,
133 	AUDIO_CTRL_ID_HEADPHONE,
134 	AUDIO_CTRL_ID_CD,
135 	AUDIO_CTRL_ID_VIDEO,
136 	AUDIO_CTRL_ID_3DDEPTH,
137 	AUDIO_CTRL_ID_3DENHANCE,
138 	AUDIO_CTRL_ID_BEEP,
139 	AUDIO_CTRL_ID_RECGAIN,
140 	AUDIO_CTRL_ID_RECSRC,
141 	AUDIO_CTRL_ID_LOOPBACK,
142 	NULL,
143 };
144 
145 /*
146  * AC'97 sources we don't want to expose.
147  */
148 const char *audigyls_badsrcs[] = {
149 	AUDIO_PORT_VIDEO,
150 	AUDIO_PORT_CD,
151 	AUDIO_PORT_STEREOMIX,
152 	AUDIO_PORT_MONOMIX,
153 	NULL,
154 };
155 
156 static unsigned int
157 read_chan(audigyls_dev_t *dev, int reg, int chn)
158 {
159 	uint32_t val;
160 
161 	mutex_enter(&dev->low_mutex);
162 	/* Pointer */
163 	OUTL(dev, PR, (reg << 16) | (chn & 0xffff));
164 	/* Data */
165 	val = INL(dev, DR);
166 	mutex_exit(&dev->low_mutex);
167 
168 	return (val);
169 }
170 
171 static void
172 write_chan(audigyls_dev_t *dev, int reg, int chn, uint32_t value)
173 {
174 	mutex_enter(&dev->low_mutex);
175 	/* Pointer */
176 	OUTL(dev, PR, (reg << 16) | (chn & 0x7));
177 	/* Data */
178 	OUTL(dev, DR, value);
179 	mutex_exit(&dev->low_mutex);
180 }
181 
182 static unsigned int
183 read_reg(audigyls_dev_t *dev, int reg)
184 {
185 	return (read_chan(dev, reg, 0));
186 }
187 
188 static void
189 write_reg(audigyls_dev_t *dev, int reg, uint32_t value)
190 {
191 	write_chan(dev, reg, 0, value);
192 }
193 
194 
195 static uint16_t
196 audigyls_read_ac97(void *arg, uint8_t index)
197 {
198 	audigyls_dev_t *dev = arg;
199 	uint16_t dtemp = 0;
200 	int i;
201 
202 	mutex_enter(&dev->low_mutex);
203 	OUTB(dev, AC97A, index);
204 	for (i = 0; i < 10000; i++) {
205 		if (INB(dev, AC97A) & 0x80)
206 			break;
207 	}
208 	if (i == 10000) {	/* Timeout */
209 		mutex_exit(&dev->low_mutex);
210 		return (0xffff);
211 	}
212 	dtemp = INW(dev, AC97D);
213 	mutex_exit(&dev->low_mutex);
214 
215 	return (dtemp);
216 }
217 
218 static void
219 audigyls_write_ac97(void *arg, uint8_t index, uint16_t data)
220 {
221 	audigyls_dev_t *dev = arg;
222 	int i;
223 
224 	mutex_enter(&dev->low_mutex);
225 	OUTB(dev, AC97A, index);
226 	for (i = 0; i < 50000; i++) {
227 		if (INB(dev, AC97A) & 0x80)
228 			break;
229 	}
230 	if (i == 50000) {
231 		mutex_exit(&dev->low_mutex);
232 		return;
233 	}
234 	OUTW(dev, AC97D, data);
235 	mutex_exit(&dev->low_mutex);
236 }
237 
238 static void
239 select_digital_enable(audigyls_dev_t *dev, int mode)
240 {
241 	/*
242 	 * Set the out3/spdif combo jack format.
243 	 * mode0=analog rear/center, 1=spdif
244 	 */
245 
246 	if (mode == 0) {
247 		write_reg(dev, SPC, 0x00000f00);
248 	} else {
249 		write_reg(dev, SPC, 0x0000000f);
250 	}
251 }
252 
253 /* only for SBLive 7.1 */
254 void
255 audigyls_i2c_write(audigyls_dev_t *dev, int reg, int data)
256 {
257 	int i, timeout, tmp;
258 
259 	tmp = (reg << 9 | data) << 16;	/* set the upper 16 bits */
260 	/* first write the command to the data reg */
261 	write_reg(dev, I2C_1, tmp);
262 	for (i = 0; i < 20; i++) {
263 		tmp = read_reg(dev, I2C_A) & ~0x6fe;
264 		/* see audigyls.pdf for bits */
265 		tmp |= 0x400 | 0x100 | 0x34;
266 		write_reg(dev, I2C_A, tmp);
267 		/* now wait till controller sets valid bit (0x100) to 0 */
268 		timeout = 0;
269 		for (;;) {
270 			tmp = read_reg(dev, I2C_A);
271 			if ((tmp & 0x100) == 0)
272 				break;
273 
274 			if (timeout > 100)
275 				break;
276 
277 			timeout++;
278 		}
279 
280 		/* transaction aborted */
281 		if (tmp & 0x200)
282 			break;
283 	}
284 }
285 
286 int
287 audigyls_spi_write(audigyls_dev_t *dev, int data)
288 {
289 	unsigned int orig;
290 	unsigned int tmp;
291 	int i, valid;
292 
293 	tmp = read_reg(dev, SPI);
294 	orig = (tmp & ~0x3ffff) | 0x30000;
295 	write_reg(dev, SPI, orig | data);
296 	valid = 0;
297 	/* Wait for status bit to return to 0 */
298 	for (i = 0; i < 1000; i++) {
299 		drv_usecwait(100);
300 		tmp = read_reg(dev, SPI);
301 		if (!(tmp & 0x10000)) {
302 			valid = 1;
303 			break;
304 		}
305 	}
306 	if (!valid)			/* Timed out */
307 		return (0);
308 
309 	return (1);
310 }
311 
312 static void
313 audigyls_update_port(audigyls_port_t *port)
314 {
315 	audigyls_dev_t *dev = port->dev;
316 	uint32_t	offset, n;
317 
318 	if (dev->suspended)
319 		return;
320 
321 	if (port->direction == AUDIGYLS_PLAY_PORT) {
322 		offset = read_chan(dev, CPFA, 0);
323 	} else {
324 		offset = read_chan(dev, CRFA, 2);
325 	}
326 
327 
328 	/* get the offset, and switch to frames */
329 	offset /= (2 * sizeof (uint16_t));
330 
331 	if (offset >= port->offset) {
332 		n = offset - port->offset;
333 	} else {
334 		n = offset + (port->buf_frames - port->offset);
335 	}
336 	port->offset = offset;
337 	port->count += n;
338 }
339 
340 static void
341 check_play_intr(audigyls_dev_t *dev)
342 {
343 	audigyls_port_t *port = dev->port[AUDIGYLS_PLAY_PORT];
344 
345 	if (!port->started)
346 		return;
347 	audio_engine_consume(port->engine);
348 }
349 
350 static void
351 check_rec_intr(audigyls_dev_t *dev)
352 {
353 	audigyls_port_t *port = dev->port[AUDIGYLS_REC_PORT];
354 
355 	if (!port->started)
356 		return;
357 	audio_engine_produce(port->engine);
358 }
359 
360 static uint_t
361 audigyls_intr(caddr_t argp, caddr_t nocare)
362 {
363 	audigyls_dev_t	*dev = (void *)argp;
364 	uint32_t	status;
365 
366 	_NOTE(ARGUNUSED(nocare));
367 	status = INL(dev, IPR);
368 
369 	if (dev->suspended) {
370 		OUTL(dev, IPR, status);		/* Acknowledge */
371 		return (DDI_INTR_UNCLAIMED);
372 	}
373 
374 	if (!(status & (INTR_IT1 | INTR_PCI))) {
375 		/* No audio interrupts pending */
376 		OUTL(dev, IPR, status);		/* Acknowledge */
377 		return (DDI_INTR_UNCLAIMED);
378 	}
379 
380 	check_play_intr(dev);
381 	check_rec_intr(dev);
382 
383 	if (dev->ksp) {
384 		AUDIGYLS_KIOP(dev)->intrs[KSTAT_INTR_HARD]++;
385 	}
386 
387 	OUTL(dev, IPR, status);		/* Acknowledge */
388 	return (DDI_INTR_CLAIMED);
389 }
390 
391 /*
392  * Audio routines
393  */
394 
395 int
396 audigyls_open(void *arg, int flag,
397     unsigned *fragfrp, unsigned *nfragsp, caddr_t *bufp)
398 {
399 	audigyls_port_t	 *port = arg;
400 	audigyls_dev_t	 *dev = port->dev;
401 
402 	_NOTE(ARGUNUSED(flag));
403 
404 	mutex_enter(&dev->mutex);
405 
406 	port->started = B_FALSE;
407 	port->count = 0;
408 	*fragfrp = port->fragfr;
409 	*nfragsp = AUDIGYLS_NUM_FRAGS;
410 	*bufp = port->buf_kaddr;
411 	audigyls_reset_port(port);
412 	mutex_exit(&dev->mutex);
413 
414 	return (0);
415 }
416 
417 void
418 audigyls_close(void *arg)
419 {
420 	audigyls_port_t *port = arg;
421 	audigyls_dev_t	 *dev = port->dev;
422 
423 	mutex_enter(&dev->mutex);
424 	audigyls_stop_port(port);
425 	port->started = B_FALSE;
426 	mutex_exit(&dev->mutex);
427 }
428 
429 int
430 audigyls_start(void *arg)
431 {
432 	audigyls_port_t *port = arg;
433 	audigyls_dev_t	*dev = port->dev;
434 
435 	mutex_enter(&dev->mutex);
436 	if (!port->started) {
437 		audigyls_start_port(port);
438 		port->started = B_TRUE;
439 	}
440 	mutex_exit(&dev->mutex);
441 	return (0);
442 }
443 
444 void
445 audigyls_stop(void *arg)
446 {
447 	audigyls_port_t	*port = arg;
448 	audigyls_dev_t	*dev = port->dev;
449 
450 	mutex_enter(&dev->mutex);
451 	if (port->started) {
452 		audigyls_stop_port(port);
453 		port->started = B_FALSE;
454 	}
455 	mutex_exit(&dev->mutex);
456 }
457 
458 int
459 audigyls_format(void *arg)
460 {
461 	_NOTE(ARGUNUSED(arg));
462 
463 	return (AUDIO_FORMAT_S16_LE);
464 }
465 
466 int
467 audigyls_channels(void *arg)
468 {
469 	audigyls_port_t	*port = arg;
470 
471 	return (port->nchan);
472 }
473 
474 int
475 audigyls_rate(void *arg)
476 {
477 	_NOTE(ARGUNUSED(arg));
478 
479 	return (48000);
480 }
481 
482 void
483 audigyls_sync(void *arg, unsigned nframes)
484 {
485 	audigyls_port_t *port = arg;
486 	_NOTE(ARGUNUSED(nframes));
487 
488 	(void) ddi_dma_sync(port->buf_dmah, 0, 0, port->syncdir);
489 }
490 
491 size_t
492 audigyls_qlen(void *arg)
493 {
494 	_NOTE(ARGUNUSED(arg));
495 	return (0);
496 }
497 
498 uint64_t
499 audigyls_count(void *arg)
500 {
501 	audigyls_port_t	*port = arg;
502 	audigyls_dev_t	*dev = port->dev;
503 	uint64_t	count;
504 
505 	mutex_enter(&dev->mutex);
506 	if (!dev->suspended)
507 		audigyls_update_port(port);
508 	count = port->count;
509 	mutex_exit(&dev->mutex);
510 	return (count);
511 }
512 
513 static void
514 audigyls_chinfo(void *arg, int chan, unsigned *offset, unsigned *incr)
515 {
516 	audigyls_port_t *port = arg;
517 
518 	if (port->direction == AUDIGYLS_PLAY_PORT) {
519 		*offset = (port->buf_frames * 2 * (chan / 2)) + (chan % 2);
520 		*incr = 2;
521 	} else {
522 		*offset = chan;
523 		*incr = 2;
524 	}
525 }
526 
527 /* private implementation bits */
528 
529 void
530 audigyls_start_port(audigyls_port_t *port)
531 {
532 	audigyls_dev_t	*dev = port->dev;
533 	uint32_t tmp;
534 
535 	ASSERT(mutex_owned(&dev->mutex));
536 
537 	if (dev->suspended || port->active)
538 		return;
539 
540 	port->active = B_TRUE;
541 	port->offset = 0;
542 	dev->nactive++;
543 
544 	if (dev->nactive == 1) {
545 		write_reg(dev, IT, dev->timer);
546 		OUTL(dev, IER, INL(dev, IER) | INTR_IT1);
547 	}
548 
549 	switch (port->direction) {
550 	case AUDIGYLS_PLAY_PORT:
551 		tmp = read_reg(dev, SA);
552 		tmp |= SA_SPA(0);
553 		tmp |= SA_SPA(1);
554 		tmp |= SA_SPA(3);
555 		write_reg(dev, SA, tmp);
556 		break;
557 
558 	case AUDIGYLS_REC_PORT:
559 		tmp = read_reg(dev, SA);
560 		tmp |= SA_SRA(2);
561 		write_reg(dev, SA, tmp);
562 		break;
563 	}
564 
565 }
566 
567 void
568 audigyls_stop_port(audigyls_port_t *port)
569 {
570 	audigyls_dev_t	*dev = port->dev;
571 	uint32_t tmp;
572 
573 	if (dev->suspended || !port->active)
574 		return;
575 
576 	port->active = B_FALSE;
577 	dev->nactive--;
578 
579 	switch (port->direction) {
580 	case AUDIGYLS_PLAY_PORT:
581 		tmp = read_reg(dev, SA);
582 		tmp &= ~SA_SPA(0);
583 		tmp &= ~SA_SPA(1);
584 		tmp &= ~SA_SPA(3);
585 		write_reg(dev, SA, tmp);
586 		break;
587 
588 	case AUDIGYLS_REC_PORT:
589 		tmp = read_reg(dev, SA);
590 		tmp &= ~SA_SRA(2);
591 		write_reg(dev, SA, tmp);
592 		break;
593 	}
594 
595 	if (dev->nactive == 0) {
596 		OUTL(dev, IER, INL(dev, IER) & ~INTR_IT1);
597 	}
598 }
599 
600 void
601 audigyls_reset_port(audigyls_port_t *port)
602 {
603 	audigyls_dev_t	*dev = port->dev;
604 
605 	ASSERT(mutex_owned(&dev->mutex));
606 
607 	if (dev->suspended)
608 		return;
609 
610 	switch (port->direction) {
611 	case AUDIGYLS_PLAY_PORT:
612 		write_chan(dev, PTCA, 0, 0);
613 		write_chan(dev, CPFA, 0, 0);
614 		write_chan(dev, CPCAV, 0, 0);
615 		write_chan(dev, PTCA, 1, 0);
616 		write_chan(dev, CPFA, 1, 0);
617 		write_chan(dev, CPCAV, 1, 0);
618 		write_chan(dev, PTCA, 3, 0);
619 		write_chan(dev, CPFA, 3, 0);
620 		write_chan(dev, CPCAV, 3, 0);
621 		break;
622 
623 	case AUDIGYLS_REC_PORT:
624 		write_chan(dev, CRFA, 2, 0);
625 		write_chan(dev, CRCAV, 2, 0);
626 		break;
627 	}
628 }
629 
630 int
631 audigyls_alloc_port(audigyls_dev_t *dev, int num)
632 {
633 	audigyls_port_t		*port;
634 	size_t			len;
635 	ddi_dma_cookie_t	cookie;
636 	uint_t			count;
637 	int			dir;
638 	unsigned		caps;
639 	audio_dev_t		*adev;
640 
641 	adev = dev->adev;
642 	port = kmem_zalloc(sizeof (*port), KM_SLEEP);
643 	dev->port[num] = port;
644 	port->dev = dev;
645 	port->started = B_FALSE;
646 	port->direction = num;
647 
648 	switch (num) {
649 	case AUDIGYLS_REC_PORT:
650 		port->syncdir = DDI_DMA_SYNC_FORKERNEL;
651 		caps = ENGINE_INPUT_CAP;
652 		dir = DDI_DMA_READ;
653 		port->nchan = 2;
654 		break;
655 	case AUDIGYLS_PLAY_PORT:
656 		port->syncdir = DDI_DMA_SYNC_FORDEV;
657 		caps = ENGINE_OUTPUT_CAP;
658 		dir = DDI_DMA_WRITE;
659 		port->nchan = 6;
660 		break;
661 	default:
662 		return (DDI_FAILURE);
663 	}
664 
665 	/* figure out fragment configuration */
666 	port->fragfr = 48000 / dev->intrs;
667 	/* we want to make sure that we are aligning on reasonable chunks */
668 	port->fragfr = (port->fragfr + 63) & ~(63);
669 
670 	/* 16 bit frames */
671 	port->fragsz = port->fragfr * 2 * port->nchan;
672 	port->buf_size = port->fragsz * AUDIGYLS_NUM_FRAGS;
673 	port->buf_frames = port->fragfr * AUDIGYLS_NUM_FRAGS;
674 
675 	/* Alloc buffers */
676 	if (ddi_dma_alloc_handle(dev->dip, &dma_attr_buf, DDI_DMA_SLEEP, NULL,
677 	    &port->buf_dmah) != DDI_SUCCESS) {
678 		audio_dev_warn(adev, "failed to allocate BUF handle");
679 		return (DDI_FAILURE);
680 	}
681 
682 	if (ddi_dma_mem_alloc(port->buf_dmah, port->buf_size,
683 	    &buf_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
684 	    &port->buf_kaddr, &len, &port->buf_acch) != DDI_SUCCESS) {
685 		audio_dev_warn(adev, "failed to allocate BUF memory");
686 		return (DDI_FAILURE);
687 	}
688 
689 	if (ddi_dma_addr_bind_handle(port->buf_dmah, NULL, port->buf_kaddr,
690 	    len, DDI_DMA_CONSISTENT | dir, DDI_DMA_SLEEP, NULL, &cookie,
691 	    &count) != DDI_SUCCESS) {
692 		audio_dev_warn(adev, "failed binding BUF DMA handle");
693 		return (DDI_FAILURE);
694 	}
695 	port->buf_paddr = cookie.dmac_address;
696 
697 	port->engine = audio_engine_alloc(&audigyls_engine_ops, caps);
698 	if (port->engine == NULL) {
699 		audio_dev_warn(adev, "audio_engine_alloc failed");
700 		return (DDI_FAILURE);
701 	}
702 
703 	audio_engine_set_private(port->engine, port);
704 	audio_dev_add_engine(adev, port->engine);
705 
706 	return (DDI_SUCCESS);
707 }
708 
709 int
710 audigyls_setup_intrs(audigyls_dev_t *dev)
711 {
712 	uint_t			ipri;
713 	int			actual;
714 	int			rv;
715 	ddi_intr_handle_t	ih[1];
716 
717 	rv = ddi_intr_alloc(dev->dip, ih, DDI_INTR_TYPE_FIXED,
718 	    0, 1, &actual, DDI_INTR_ALLOC_STRICT);
719 	if ((rv != DDI_SUCCESS) || (actual != 1)) {
720 		audio_dev_warn(dev->adev,
721 		    "Can't alloc interrupt handle (rv %d actual %d)",
722 		    rv, actual);
723 		return (DDI_FAILURE);
724 	}
725 
726 	if (ddi_intr_get_pri(ih[0], &ipri) != DDI_SUCCESS) {
727 		audio_dev_warn(dev->adev, "Can't get interrupt priority");
728 		(void) ddi_intr_free(ih[0]);
729 		return (DDI_FAILURE);
730 	}
731 
732 	if (ddi_intr_add_handler(ih[0], audigyls_intr, dev, NULL) !=
733 	    DDI_SUCCESS) {
734 		audio_dev_warn(dev->adev, "Can't add interrupt handler");
735 		(void) ddi_intr_free(ih[0]);
736 		return (DDI_FAILURE);
737 	}
738 
739 	dev->ih = ih[0];
740 	mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, DDI_INTR_PRI(ipri));
741 	mutex_init(&dev->low_mutex, NULL, MUTEX_DRIVER, DDI_INTR_PRI(ipri));
742 	return (DDI_SUCCESS);
743 }
744 
745 void
746 audigyls_del_controls(audigyls_dev_t *dev)
747 {
748 	for (int i = 0; i < CTL_NUM; i++) {
749 		if (dev->controls[i].ctrl) {
750 			audio_dev_del_control(dev->controls[i].ctrl);
751 			dev->controls[i].ctrl = NULL;
752 		}
753 	}
754 }
755 
756 void
757 audigyls_destroy(audigyls_dev_t *dev)
758 {
759 	if (dev->ih != NULL) {
760 		(void) ddi_intr_disable(dev->ih);
761 		(void) ddi_intr_remove_handler(dev->ih);
762 		(void) ddi_intr_free(dev->ih);
763 		mutex_destroy(&dev->mutex);
764 		mutex_destroy(&dev->low_mutex);
765 	}
766 
767 	if (dev->ksp) {
768 		kstat_delete(dev->ksp);
769 	}
770 
771 	for (int i = 0; i < AUDIGYLS_NUM_PORT; i++) {
772 		audigyls_port_t *port = dev->port[i];
773 		if (!port)
774 			continue;
775 		if (port->engine) {
776 			audio_dev_remove_engine(dev->adev, port->engine);
777 			audio_engine_free(port->engine);
778 		}
779 		if (port->buf_paddr) {
780 			(void) ddi_dma_unbind_handle(port->buf_dmah);
781 		}
782 		if (port->buf_acch) {
783 			ddi_dma_mem_free(&port->buf_acch);
784 		}
785 		if (port->buf_dmah) {
786 			ddi_dma_free_handle(&port->buf_dmah);
787 		}
788 		kmem_free(port, sizeof (*port));
789 	}
790 
791 	if (dev->ac97 != NULL) {
792 		ac97_free(dev->ac97);
793 	}
794 
795 	audigyls_del_controls(dev);
796 
797 	if (dev->adev != NULL) {
798 		audio_dev_free(dev->adev);
799 	}
800 	if (dev->regsh != NULL) {
801 		ddi_regs_map_free(&dev->regsh);
802 	}
803 	if (dev->pcih != NULL) {
804 		pci_config_teardown(&dev->pcih);
805 	}
806 	kmem_free(dev, sizeof (*dev));
807 }
808 
809 void
810 audigyls_hwinit(audigyls_dev_t *dev)
811 {
812 	static unsigned int spi_dac[] = {
813 		0x00ff, 0x02ff, 0x0400, 0x520, 0x0620, 0x08ff, 0x0aff, 0x0cff,
814 		0x0eff, 0x10ff, 0x1200, 0x1400, 0x1800, 0x1aff, 0x1cff,
815 		0x1e00, 0x0530, 0x0602, 0x0622, 0x1400,
816 	};
817 
818 	uint32_t	tmp;
819 	int		i, tries;
820 	uint32_t	paddr;
821 	uint32_t	chunksz;
822 	audigyls_port_t	*port;
823 
824 
825 	/* Set the orange jack to be analog out or S/PDIF */
826 	select_digital_enable(dev, dev->digital_enable);
827 
828 	/*
829 	 * In P17, there's 8 GPIO pins.
830 	 * GPIO register: 0x00XXYYZZ
831 	 * XX: Configure GPIO to be either GPI (0) or GPO (1).
832 	 * YY: GPO values, applicable if the pin is configure to be GPO.
833 	 * ZZ: GPI values, applicable if the pin is configure to be GPI.
834 	 *
835 	 * in SB570, pin 0-4 and 6 is used as GPO and pin 5 and 7 is
836 	 * used as GPI.
837 	 *
838 	 * GPO0:
839 	 * 1 ==> Analog output
840 	 * 0 ==> Digital output
841 	 * GPO1:
842 	 * 1 ==> Enable output on card
843 	 * 0 ==> Disable output on card
844 	 * GPO2:
845 	 * 1 ==> Enable Mic Bias and Mic Path
846 	 * 0 ==> Disable Mic Bias and Mic Path
847 	 * GPO3:
848 	 * 1 ==> Disable SPDIF-IO output
849 	 * 0 ==> Enable SPDIF-IO output
850 	 * GPO4 and GPO6:
851 	 * DAC sampling rate selection:
852 	 * Not applicable to SB570 since DAC is controlled through SPI
853 	 * GPI5:
854 	 * 1 ==> Front Panel is not connected
855 	 * 0 ==> Front Panel is connected
856 	 * GPI7:
857 	 * 1 ==> Front Panel Headphone is not connected
858 	 * 0 ==> Front Panel Headphone is connected
859 	 */
860 	if (dev->ac97)
861 		OUTL(dev, GPIO, 0x005f03a3);
862 	else {
863 		/* for SBLive 7.1 */
864 		OUTL(dev, GPIO, 0x005f4301);
865 
866 		audigyls_i2c_write(dev, 0x15, 0x2);
867 		tries = 0;
868 	again:
869 		for (i = 0; i < sizeof (spi_dac); i++) {
870 			if (!audigyls_spi_write(dev, spi_dac[i]) &&
871 			    tries < 100) {
872 				tries++;
873 				goto again;
874 			}
875 		}
876 	}
877 
878 	OUTL(dev, IER, INTR_PCI);
879 	OUTL(dev, HC, 0x00000009);	/* Enable audio, use 48 kHz */
880 
881 	tmp = read_chan(dev, SRCTL, 0);
882 	if (dev->ac97)
883 		tmp |= 0xf0c81000;	/* Record src0/src1 from ac97 */
884 	else
885 		tmp |= 0x50c81000;	/* Record src0/src1 from I2SIN */
886 	tmp &= ~0x0303c00f;		/* Set sample rates to 48 kHz */
887 	write_chan(dev, SRCTL, 0, tmp);
888 
889 	write_reg(dev, HMIXMAP_I2S, 0x76543210);	/* Default out route */
890 	write_reg(dev, AUDCTL, 0x0f0f003f);	/* Enable all outputs */
891 
892 	/* All audio stopped! */
893 	write_reg(dev, SA, 0);
894 
895 	for (i = 0; i < 4; i++) {
896 		/*
897 		 * Reset DMA pointers and counters.  Note that we do
898 		 * not use scatter/gather.
899 		 */
900 		write_chan(dev, PTBA, i, 0);
901 		write_chan(dev, PTBS, i, 0);
902 		write_chan(dev, PTCA, i, 0);
903 
904 		write_chan(dev, CPFA, i, 0);
905 		write_chan(dev, PFEA, i, 0);
906 		write_chan(dev, CPCAV, i, 0);
907 
908 		write_chan(dev, CRFA, i, 0);
909 		write_chan(dev, CRCAV, i, 0);
910 	}
911 
912 	/*
913 	 * The 5.1 play port made up channels 0, 1, and 3.  The record
914 	 * port is channel 2.
915 	 */
916 	port = dev->port[AUDIGYLS_PLAY_PORT];
917 	paddr = port->buf_paddr;
918 	chunksz = port->buf_frames * 4;
919 	write_chan(dev, PFBA, 0, paddr);
920 	write_chan(dev, PFBS, 0, chunksz << 16);
921 	paddr += chunksz;
922 	write_chan(dev, PFBA, 1, paddr);
923 	write_chan(dev, PFBS, 1, chunksz << 16);
924 	paddr += chunksz;
925 	write_chan(dev, PFBA, 3, paddr);
926 	write_chan(dev, PFBS, 3, chunksz << 16);
927 
928 	/* Record */
929 	port = dev->port[AUDIGYLS_REC_PORT];
930 	paddr = port->buf_paddr;
931 	chunksz = port->buf_frames * 4;
932 	write_chan(dev, RFBA, 2, paddr);
933 	write_chan(dev, RFBS, 2, chunksz << 16);
934 
935 	/* Set sample rates to 48 kHz. */
936 	tmp = read_chan(dev, SRCTL, 0) & ~0x0303c00f;
937 	write_chan(dev, SRCTL, 0, tmp);
938 
939 	write_reg(dev, SCS0, 0x02108004);	/* Audio */
940 	write_reg(dev, SCS1, 0x02108004);	/* Audio */
941 	write_reg(dev, SCS2, 0x02108004);	/* Audio */
942 	write_reg(dev, SCS3, 0x02108004);	/* Audio */
943 }
944 
945 #define	PLAYCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY)
946 #define	RECCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC)
947 #define	MONCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR)
948 #define	PCMVOL	(PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL)
949 #define	MAINVOL	(PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL)
950 #define	RECVOL	(RECCTL | AUDIO_CTRL_FLAG_RECVOL)
951 #define	MONVOL	(MONCTL | AUDIO_CTRL_FLAG_MONVOL)
952 
953 #define	MASK(nbits)	((1 << (nbits)) - 1)
954 #define	SCALE(val, nbits)	\
955 	((uint8_t)((((val) * MASK(nbits)) / 100)) << (8 - (nbits)))
956 
957 static uint32_t
958 audigyls_stereo_scale(uint32_t value, uint8_t bits)
959 {
960 	uint8_t			left, right;
961 	uint32_t		val;
962 
963 	left = (value >> 8) & 0xff;
964 	right = value & 0xff;
965 
966 	val = (((left * ((1 << bits) - 1) / 100) << 8) |
967 	    (right * ((1 << bits) - 1) / 100));
968 	return (val);
969 }
970 
971 static void
972 audigyls_configure_mixer(audigyls_dev_t *dev)
973 {
974 	unsigned int	r, v1, v2;
975 
976 	/* output items */
977 	/* front */
978 	r = 0xffff - audigyls_stereo_scale(dev->controls[CTL_FRONT].val, 8);
979 	r = (r << 16) | r;
980 	write_chan(dev, MIXVOL_I2S, 0, r);
981 
982 	/* surround */
983 	r = 0xffff - audigyls_stereo_scale(dev->controls[CTL_SURROUND].val, 8);
984 	r = (r << 16) | r;
985 	write_chan(dev, MIXVOL_I2S, 3, r);
986 
987 	/* center/lfe */
988 	v1 = 255 - SCALE(dev->controls[CTL_CENTER].val, 8);
989 	v2 = 255 - SCALE(dev->controls[CTL_LFE].val, 8);
990 	r = (v1 << 8) | v2;
991 	r = (r << 16) | r;
992 	write_chan(dev, MIXVOL_I2S, 1, r);
993 
994 	/* spread */
995 	r = dev->controls[CTL_SPREAD].val ? 0x10101010 : 0x76543210;
996 	write_reg(dev, HMIXMAP_I2S, r);
997 
998 	/* input items */
999 
1000 	/* recgain */
1001 	v1 = dev->controls[CTL_RECORDVOL].val;
1002 	if (dev->ac97_recgain && !dev->controls[CTL_LOOP].val) {
1003 		/*
1004 		 * For AC'97, we use the AC'97 record gain, unless we are
1005 		 * in loopback.
1006 		 */
1007 		(void) ac97_control_set(dev->ac97_recgain, v1);
1008 		write_reg(dev, P17RECVOLL, 0x30303030);
1009 		write_reg(dev, P17RECVOLH, 0x30303030);
1010 	} else {
1011 		/*
1012 		 * Otherwise we set the P17 gain.
1013 		 */
1014 		r = 0xffff - audigyls_stereo_scale(v1, 8);
1015 		r = r << 16 | r;
1016 		write_reg(dev, P17RECVOLL, r);
1017 		write_reg(dev, P17RECVOLH, r);
1018 	}
1019 
1020 	/* monitor gain */
1021 	if (dev->ac97) {
1022 		/* AC'97 monitor gain is done by the AC'97 codec */
1023 		write_chan(dev, SRCTL, 1, 0x30303030);
1024 		write_reg(dev, SMIXMAP_I2S, 0x10101076);
1025 	} else {
1026 		/* For non-AC'97 devices, just a single master monitor gain */
1027 		r = 255 - SCALE(dev->controls[CTL_MONGAIN].val, 8);
1028 		write_chan(dev, SRCTL, 1, 0xffff0000 | r << 8 | r);
1029 		if (r != 0xff) {
1030 			write_reg(dev, SMIXMAP_I2S, 0x10101076);
1031 		} else {
1032 			write_reg(dev, SMIXMAP_I2S, 0x10101010);
1033 		}
1034 	}
1035 
1036 	/* record source */
1037 	if (dev->ac97_recsrc != NULL) {
1038 		(void) ac97_control_set(dev->ac97_recsrc,
1039 		    dev->controls[CTL_RECSRC].val);
1040 		v1 = RECSEL_AC97;	/* Audigy LS */
1041 	} else {
1042 		switch (dev->controls[CTL_RECSRC].val) {
1043 		case 1:
1044 			audigyls_i2c_write(dev, 0x15, 0x2);   /* Mic */
1045 			OUTL(dev, GPIO, INL(dev, GPIO) | 0x400);
1046 			break;
1047 
1048 		case 2:
1049 			audigyls_i2c_write(dev, 0x15, 0x4);   /* Line */
1050 			OUTL(dev, GPIO, INL(dev, GPIO) & ~0x400);
1051 			break;
1052 		}
1053 		v1 = RECSEL_I2SIN;	/* SB 7.1 value */
1054 	}
1055 
1056 	/* If loopback, record what you hear instead */
1057 
1058 	if (dev->controls[CTL_LOOP].val) {
1059 		r = 0;
1060 		v1 = RECSEL_I2SOUT;
1061 		r |= (v1 << 28) | (v1 << 24) | (v1 << 20) | (v1 << 16) | v2;
1062 	} else {
1063 		/*
1064 		 * You'd think this would be the same as the logic
1065 		 * above, but experience shows that what you need for
1066 		 * loopback is different.  This whole thing looks
1067 		 * particularly fishy to me.  I suspect someone has
1068 		 * made a mistake somewhere.  But I can't seem to
1069 		 * figure out where it lies.
1070 		 */
1071 		r = 0xe4;
1072 		for (int i = 0; i < 4; i++)
1073 			r |= v1 << (16 + i * 3);	/* Select input */
1074 	}
1075 
1076 	write_reg(dev, P17RECSEL, r);
1077 }
1078 
1079 static int
1080 audigyls_set_control(void *arg, uint64_t val)
1081 {
1082 	audigyls_ctrl_t	*pc = arg;
1083 	audigyls_dev_t	*dev = pc->dev;
1084 
1085 	switch (pc->num) {
1086 
1087 	case CTL_FRONT:
1088 	case CTL_SURROUND:
1089 	case CTL_RECORDVOL:
1090 		if (((val & 0xff) > 100) ||
1091 		    (((val & 0xff00) >> 8) > 100) ||
1092 		    ((val & ~0xffff) != 0)) {
1093 			return (EINVAL);
1094 		}
1095 		break;
1096 
1097 	case CTL_CENTER:
1098 	case CTL_LFE:
1099 	case CTL_MONGAIN:
1100 		if (val > 100) {
1101 			return (EINVAL);
1102 		}
1103 		break;
1104 
1105 	case CTL_RECSRC:
1106 		if (((1U << val) & (dev->recmask)) == 0) {
1107 			return (EINVAL);
1108 		}
1109 		break;
1110 
1111 	case CTL_SPREAD:
1112 	case CTL_LOOP:
1113 		switch (val) {
1114 		case 0:
1115 		case 1:
1116 			break;
1117 		default:
1118 			return (EINVAL);
1119 		}
1120 	}
1121 
1122 	mutex_enter(&dev->mutex);
1123 	pc->val = val;
1124 	if (!dev->suspended) {
1125 		audigyls_configure_mixer(dev);
1126 	}
1127 	mutex_exit(&dev->mutex);
1128 
1129 	return (0);
1130 }
1131 
1132 static int
1133 audigyls_get_control(void *arg, uint64_t *val)
1134 {
1135 	audigyls_ctrl_t	*pc = arg;
1136 	audigyls_dev_t	*dev = pc->dev;
1137 
1138 	mutex_enter(&dev->mutex);
1139 	*val = pc->val;
1140 	mutex_exit(&dev->mutex);
1141 	return (0);
1142 }
1143 
1144 static void
1145 audigyls_alloc_ctrl(audigyls_dev_t *dev, uint32_t num, uint64_t val)
1146 {
1147 	audio_ctrl_desc_t	desc;
1148 	audigyls_ctrl_t		*pc;
1149 
1150 	bzero(&desc, sizeof (desc));
1151 
1152 	pc = &dev->controls[num];
1153 	pc->num = num;
1154 	pc->dev = dev;
1155 
1156 
1157 	switch (num) {
1158 	case CTL_FRONT:
1159 		desc.acd_name = AUDIO_CTRL_ID_FRONT;
1160 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1161 		desc.acd_minvalue = 0;
1162 		desc.acd_maxvalue = 100;
1163 		desc.acd_flags = MAINVOL;
1164 		break;
1165 
1166 	case CTL_SURROUND:
1167 		desc.acd_name = AUDIO_CTRL_ID_SURROUND;
1168 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1169 		desc.acd_minvalue = 0;
1170 		desc.acd_maxvalue = 100;
1171 		desc.acd_flags = MAINVOL;
1172 		break;
1173 
1174 	case CTL_CENTER:
1175 		desc.acd_name = AUDIO_CTRL_ID_CENTER;
1176 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1177 		desc.acd_minvalue = 0;
1178 		desc.acd_maxvalue = 100;
1179 		desc.acd_flags = MAINVOL;
1180 		break;
1181 
1182 	case CTL_LFE:
1183 		desc.acd_name = AUDIO_CTRL_ID_LFE;
1184 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1185 		desc.acd_minvalue = 0;
1186 		desc.acd_maxvalue = 100;
1187 		desc.acd_flags = MAINVOL;
1188 		break;
1189 
1190 	case CTL_RECORDVOL:
1191 		desc.acd_name = AUDIO_CTRL_ID_RECGAIN;
1192 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1193 		desc.acd_minvalue = 0;
1194 		desc.acd_maxvalue = 100;
1195 		desc.acd_flags = RECVOL;
1196 		break;
1197 
1198 	case CTL_RECSRC:
1199 		desc.acd_name = AUDIO_CTRL_ID_RECSRC;
1200 		desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
1201 		desc.acd_flags = RECCTL;
1202 
1203 		/*
1204 		 * For AC'97 devices, we want to expose the reasonable
1205 		 * AC'97 input sources, but suppress the stereomix,
1206 		 * because we use loopback instead.
1207 		 */
1208 		if (dev->ac97_recsrc) {
1209 			int i, j;
1210 			const char *n;
1211 			const audio_ctrl_desc_t *adp;
1212 
1213 			adp = ac97_control_desc(dev->ac97_recsrc);
1214 			for (i = 0; i < 64; i++) {
1215 				n = adp->acd_enum[i];
1216 
1217 				if (((adp->acd_minvalue & (1 << i)) == 0) ||
1218 				    (n == NULL)) {
1219 					continue;
1220 				}
1221 				for (j = 0; audigyls_badsrcs[j]; j++) {
1222 					if (strcmp(n, audigyls_badsrcs[j])
1223 					    == 0) {
1224 						n = NULL;
1225 						break;
1226 					}
1227 				}
1228 				if (n) {
1229 					desc.acd_enum[i] = n;
1230 					dev->recmask |= (1 << i);
1231 				}
1232 			}
1233 			desc.acd_minvalue = desc.acd_maxvalue = dev->recmask;
1234 		} else {
1235 			dev->recmask = 3;
1236 			desc.acd_minvalue = 3;
1237 			desc.acd_maxvalue = 3;
1238 			desc.acd_enum[0] = AUDIO_PORT_MIC;
1239 			desc.acd_enum[1] = AUDIO_PORT_LINEIN;
1240 		}
1241 		break;
1242 
1243 	case CTL_MONGAIN:
1244 		ASSERT(!dev->ac97);
1245 		desc.acd_name = AUDIO_CTRL_ID_MONGAIN;
1246 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1247 		desc.acd_minvalue = 0;
1248 		desc.acd_maxvalue = 100;
1249 		desc.acd_flags = MONVOL;
1250 		break;
1251 
1252 	case CTL_SPREAD:
1253 		desc.acd_name = AUDIO_CTRL_ID_SPREAD;
1254 		desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN;
1255 		desc.acd_minvalue = 0;
1256 		desc.acd_maxvalue = 1;
1257 		desc.acd_flags = PLAYCTL;
1258 		break;
1259 
1260 	case CTL_LOOP:
1261 		desc.acd_name = AUDIO_CTRL_ID_LOOPBACK;
1262 		desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN;
1263 		desc.acd_minvalue = 0;
1264 		desc.acd_maxvalue = 1;
1265 		desc.acd_flags = RECCTL;
1266 		break;
1267 	}
1268 
1269 	pc->val = val;
1270 	pc->ctrl = audio_dev_add_control(dev->adev, &desc,
1271 	    audigyls_get_control, audigyls_set_control, pc);
1272 }
1273 
1274 static void
1275 audigyls_add_controls(audigyls_dev_t *dev)
1276 {
1277 	(void) audio_dev_add_soft_volume(dev->adev);
1278 
1279 	audigyls_alloc_ctrl(dev, CTL_FRONT, 75 | (75 << 8));
1280 	audigyls_alloc_ctrl(dev, CTL_SURROUND, 75 | (75 << 8));
1281 	audigyls_alloc_ctrl(dev, CTL_CENTER, 75);
1282 	audigyls_alloc_ctrl(dev, CTL_LFE, 75);
1283 	audigyls_alloc_ctrl(dev, CTL_RECORDVOL, 75 | (75 << 8));
1284 	audigyls_alloc_ctrl(dev, CTL_RECSRC, 1);
1285 	audigyls_alloc_ctrl(dev, CTL_SPREAD, 0);
1286 	audigyls_alloc_ctrl(dev, CTL_LOOP, 0);
1287 	if (!dev->ac97) {
1288 		audigyls_alloc_ctrl(dev, CTL_MONGAIN, 0);
1289 	}
1290 }
1291 
1292 int
1293 audigyls_attach(dev_info_t *dip)
1294 {
1295 	uint16_t	pci_command, vendor, device;
1296 	uint32_t	subdevice;
1297 	audigyls_dev_t	*dev;
1298 	ddi_acc_handle_t pcih;
1299 	const char	*name, *version;
1300 	boolean_t	ac97 = B_FALSE;
1301 
1302 	dev = kmem_zalloc(sizeof (*dev), KM_SLEEP);
1303 	dev->dip = dip;
1304 	ddi_set_driver_private(dip, dev);
1305 
1306 	if ((dev->adev = audio_dev_alloc(dip, 0)) == NULL) {
1307 		cmn_err(CE_WARN, "audio_dev_alloc failed");
1308 		goto error;
1309 	}
1310 
1311 	if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) {
1312 		audio_dev_warn(dev->adev, "pci_config_setup failed");
1313 		goto error;
1314 	}
1315 	dev->pcih = pcih;
1316 
1317 	vendor = pci_config_get16(pcih, PCI_CONF_VENID);
1318 	device = pci_config_get16(pcih, PCI_CONF_DEVID);
1319 	subdevice = pci_config_get16(pcih, PCI_CONF_SUBVENID);
1320 	subdevice <<= 16;
1321 	subdevice |= pci_config_get16(pcih, PCI_CONF_SUBSYSID);
1322 	if (vendor != PCI_VENDOR_ID_CREATIVE ||
1323 	    device != PCI_DEVICE_ID_CREATIVE_AUDIGYLS) {
1324 		audio_dev_warn(dev->adev, "Hardware not recognized "
1325 		    "(vendor=%x, dev=%x)", vendor, device);
1326 		goto error;
1327 	}
1328 
1329 	pci_command = pci_config_get16(pcih, PCI_CONF_COMM);
1330 	pci_command |= PCI_COMM_ME | PCI_COMM_IO;
1331 	pci_config_put16(pcih, PCI_CONF_COMM, pci_command);
1332 
1333 	if ((ddi_regs_map_setup(dip, 1, &dev->base, 0, 0, &dev_attr,
1334 	    &dev->regsh)) != DDI_SUCCESS) {
1335 		audio_dev_warn(dev->adev, "failed to map registers");
1336 		goto error;
1337 	}
1338 
1339 	/* Function of the orange jack: 0=analog, 1=digital */
1340 	dev->digital_enable = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
1341 	    DDI_PROP_DONTPASS, "digital-enable", 0);
1342 
1343 	if (audigyls_setup_intrs(dev) != DDI_SUCCESS)
1344 		goto error;
1345 
1346 	dev->intrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
1347 	    DDI_PROP_DONTPASS, "interrupt-rate", AUDIGYLS_INTRS);
1348 
1349 	/* make sure the values are good */
1350 	if (dev->intrs < AUDIGYLS_MIN_INTRS) {
1351 		audio_dev_warn(dev->adev,
1352 		    "interrupt-rate too low, %d, reset to %d",
1353 		    dev->intrs, AUDIGYLS_INTRS);
1354 		dev->intrs = AUDIGYLS_INTRS;
1355 	} else if (dev->intrs > AUDIGYLS_MAX_INTRS) {
1356 		audio_dev_warn(dev->adev,
1357 		    "interrupt-rate too high, %d, reset to %d",
1358 		    dev->intrs, AUDIGYLS_INTRS);
1359 		dev->intrs = AUDIGYLS_INTRS;
1360 	}
1361 
1362 	dev->timer = (192000 / dev->intrs) << 16;
1363 
1364 	switch (subdevice) {
1365 	case 0x11021001:	/* SB0310 */
1366 	case 0x11021002:	/* SB0310 */
1367 	case 0x11021005:	/* SB0310b */
1368 		name = "Creative Audigy LS";
1369 		version = "SB0310";	/* could also be SB0312 */
1370 		ac97 = B_TRUE;
1371 		break;
1372 	case 0x11021006:
1373 		name = "Creative Sound Blaster Live! 24 bit";
1374 		version = "SB0410";
1375 		break;
1376 	case 0x11021007:	/* Dell OEM version */
1377 		name = "Creative Sound Blaster Live! 24 bit";
1378 		version = "SB0413";
1379 		break;
1380 	case 0x1102100a:
1381 		name = "Creative Audigy SE";
1382 		version = "SB0570";
1383 		break;
1384 	case 0x11021011:
1385 		name = "Creative Audigy SE OEM";
1386 		version = "SB0570a";
1387 		break;
1388 	case 0x11021012:
1389 		name = "Creative X-Fi Extreme Audio";
1390 		version = "SB0790";
1391 		break;
1392 	case 0x14621009:
1393 		name = "MSI K8N Diamond MB";
1394 		version = "SB0438";
1395 		break;
1396 	case 0x12973038:
1397 		name = "Shuttle XPC SD31P";
1398 		version = "SD31P";
1399 		break;
1400 	case 0x12973041:
1401 		name = "Shuttle XPC SD11G5";
1402 		version = "SD11G5";
1403 		break;
1404 	default:
1405 		name = "Creative Audigy LS";
1406 		version = NULL;
1407 		break;
1408 	}
1409 
1410 	audio_dev_set_description(dev->adev, name);
1411 	if (version)
1412 		audio_dev_set_version(dev->adev, version);
1413 
1414 	if (ac97) {
1415 		ac97_ctrl_t *ctrl;
1416 
1417 		/* Original Audigy LS revision (AC97 based) */
1418 		dev->ac97 = ac97_allocate(dev->adev, dip,
1419 		    audigyls_read_ac97, audigyls_write_ac97, dev);
1420 		if (dev->ac97 == NULL) {
1421 			audio_dev_warn(dev->adev,
1422 			    "failed to allocate ac97 handle");
1423 			goto error;
1424 		}
1425 
1426 		ac97_probe_controls(dev->ac97);
1427 
1428 		/* remove the AC'97 controls we don't want to expose */
1429 		for (int i = 0; audigyls_remove_ac97[i]; i++) {
1430 			ctrl = ac97_control_find(dev->ac97,
1431 			    audigyls_remove_ac97[i]);
1432 			if (ctrl != NULL) {
1433 				ac97_control_unregister(ctrl);
1434 			}
1435 		}
1436 
1437 		dev->ac97_recgain = ac97_control_find(dev->ac97,
1438 		    AUDIO_CTRL_ID_RECGAIN);
1439 		dev->ac97_recsrc = ac97_control_find(dev->ac97,
1440 		    AUDIO_CTRL_ID_RECSRC);
1441 	}
1442 
1443 	audigyls_add_controls(dev);
1444 
1445 	if (dev->ac97) {
1446 		ac97_register_controls(dev->ac97);
1447 	}
1448 
1449 	if (audigyls_alloc_port(dev, AUDIGYLS_PLAY_PORT) != DDI_SUCCESS)
1450 		goto error;
1451 	if (audigyls_alloc_port(dev, AUDIGYLS_REC_PORT) != DDI_SUCCESS)
1452 		goto error;
1453 
1454 	audigyls_hwinit(dev);
1455 
1456 	audigyls_configure_mixer(dev);
1457 
1458 	/* set up kernel statistics */
1459 	if ((dev->ksp = kstat_create(AUDIGYLS_NAME, ddi_get_instance(dip),
1460 	    AUDIGYLS_NAME, "controller", KSTAT_TYPE_INTR, 1,
1461 	    KSTAT_FLAG_PERSISTENT)) != NULL) {
1462 		kstat_install(dev->ksp);
1463 	}
1464 
1465 	if (audio_dev_register(dev->adev) != DDI_SUCCESS) {
1466 		audio_dev_warn(dev->adev, "unable to register with framework");
1467 		goto error;
1468 	}
1469 
1470 	(void) ddi_intr_enable(dev->ih);
1471 	ddi_report_dev(dip);
1472 
1473 	return (DDI_SUCCESS);
1474 
1475 error:
1476 	audigyls_destroy(dev);
1477 	return (DDI_FAILURE);
1478 }
1479 
1480 int
1481 audigyls_resume(dev_info_t *dip)
1482 {
1483 	audigyls_dev_t *dev;
1484 	audigyls_port_t *port;
1485 
1486 	dev = ddi_get_driver_private(dip);
1487 
1488 	for (int i = 0; i < AUDIGYLS_NUM_PORT; i++) {
1489 		port = dev->port[i];
1490 		audio_engine_reset(port->engine);
1491 	}
1492 
1493 	audigyls_hwinit(dev);
1494 
1495 	/* allow ac97 operations again */
1496 	if (dev->ac97)
1497 		ac97_resume(dev->ac97);
1498 
1499 	audigyls_configure_mixer(dev);
1500 
1501 	mutex_enter(&dev->mutex);
1502 	dev->suspended = B_FALSE;
1503 
1504 	for (int i = 0; i < AUDIGYLS_NUM_PORT; i++) {
1505 
1506 		port = dev->port[i];
1507 
1508 		audigyls_reset_port(port);
1509 
1510 		if (port->started) {
1511 			audigyls_start_port(port);
1512 		}
1513 	}
1514 
1515 	mutex_exit(&dev->mutex);
1516 	return (DDI_SUCCESS);
1517 }
1518 
1519 int
1520 audigyls_detach(audigyls_dev_t *dev)
1521 {
1522 	if (audio_dev_unregister(dev->adev) != DDI_SUCCESS)
1523 		return (DDI_FAILURE);
1524 
1525 	audigyls_destroy(dev);
1526 	return (DDI_SUCCESS);
1527 }
1528 
1529 int
1530 audigyls_suspend(audigyls_dev_t *dev)
1531 {
1532 	if (dev->ac97)
1533 		ac97_suspend(dev->ac97);
1534 
1535 	mutex_enter(&dev->mutex);
1536 	for (int i = 0; i < AUDIGYLS_NUM_PORT; i++) {
1537 
1538 		audigyls_port_t *port = dev->port[i];
1539 		audigyls_stop_port(port);
1540 	}
1541 	dev->suspended = B_TRUE;
1542 	mutex_exit(&dev->mutex);
1543 	return (DDI_SUCCESS);
1544 }
1545 
1546 static int audigyls_ddi_attach(dev_info_t *, ddi_attach_cmd_t);
1547 static int audigyls_ddi_detach(dev_info_t *, ddi_detach_cmd_t);
1548 static int audigyls_ddi_quiesce(dev_info_t *);
1549 
1550 static struct dev_ops audigyls_dev_ops = {
1551 	DEVO_REV,		/* rev */
1552 	0,			/* refcnt */
1553 	NULL,			/* getinfo */
1554 	nulldev,		/* identify */
1555 	nulldev,		/* probe */
1556 	audigyls_ddi_attach,	/* attach */
1557 	audigyls_ddi_detach,	/* detach */
1558 	nodev,			/* reset */
1559 	NULL,			/* cb_ops */
1560 	NULL,			/* bus_ops */
1561 	NULL,			/* power */
1562 	audigyls_ddi_quiesce,	/* quiesce */
1563 };
1564 
1565 static struct modldrv audigyls_modldrv = {
1566 	&mod_driverops,			/* drv_modops */
1567 	"Creative Audigy LS Audio",		/* linkinfo */
1568 	&audigyls_dev_ops,			/* dev_ops */
1569 };
1570 
1571 static struct modlinkage modlinkage = {
1572 	MODREV_1,
1573 	{ &audigyls_modldrv, NULL }
1574 };
1575 
1576 int
1577 _init(void)
1578 {
1579 	int	rv;
1580 
1581 	audio_init_ops(&audigyls_dev_ops, AUDIGYLS_NAME);
1582 	if ((rv = mod_install(&modlinkage)) != 0) {
1583 		audio_fini_ops(&audigyls_dev_ops);
1584 	}
1585 	return (rv);
1586 }
1587 
1588 int
1589 _fini(void)
1590 {
1591 	int	rv;
1592 
1593 	if ((rv = mod_remove(&modlinkage)) == 0) {
1594 		audio_fini_ops(&audigyls_dev_ops);
1595 	}
1596 	return (rv);
1597 }
1598 
1599 int
1600 _info(struct modinfo *modinfop)
1601 {
1602 	return (mod_info(&modlinkage, modinfop));
1603 }
1604 
1605 int
1606 audigyls_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1607 {
1608 	switch (cmd) {
1609 	case DDI_ATTACH:
1610 		return (audigyls_attach(dip));
1611 
1612 	case DDI_RESUME:
1613 		return (audigyls_resume(dip));
1614 
1615 	default:
1616 		return (DDI_FAILURE);
1617 	}
1618 }
1619 
1620 int
1621 audigyls_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1622 {
1623 	audigyls_dev_t *dev;
1624 
1625 	dev = ddi_get_driver_private(dip);
1626 
1627 	switch (cmd) {
1628 	case DDI_DETACH:
1629 		return (audigyls_detach(dev));
1630 
1631 	case DDI_SUSPEND:
1632 		return (audigyls_suspend(dev));
1633 
1634 	default:
1635 		return (DDI_FAILURE);
1636 	}
1637 }
1638 
1639 int
1640 audigyls_ddi_quiesce(dev_info_t *dip)
1641 {
1642 	audigyls_dev_t	*dev;
1643 	uint32_t status;
1644 
1645 	dev = ddi_get_driver_private(dip);
1646 
1647 	for (int i = 0; i < AUDIGYLS_NUM_PORT; i++) {
1648 
1649 		audigyls_port_t *port = dev->port[i];
1650 		audigyls_stop_port(port);
1651 	}
1652 
1653 	/*
1654 	 * Turn off the hardware
1655 	 */
1656 
1657 	write_reg(dev, SA, 0);
1658 	OUTL(dev, IER, 0);	/* Interrupt disable */
1659 	write_reg(dev, AIE, 0);	/* Disable audio interrupts */
1660 	status = INL(dev, IPR);
1661 	OUTL(dev, IPR, status);	/* Acknowledge */
1662 	return (DDI_SUCCESS);
1663 }
1664