xref: /illumos-gate/usr/src/uts/common/io/audio/drv/audioixp/audioixp.c (revision 46b592853d0f4f11781b6b0a7533f267c6aee132)
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 /*
27  * audioixp Audio Driver
28  *
29  * This driver supports audio hardware integrated in ATI IXP400 chipset.
30  *
31  * The IXP400 audio core is an AC'97 controller, which has independent
32  * channels for PCM in, PCM out. The AC'97 controller is a PCI bus master
33  * with scatter/gather support. Each channel has a DMA engine. Currently,
34  * we use only the PCM in and PCM out channels. Each DMA engine uses one
35  * buffer descriptor list.  Each entry contains a pointer to a data buffer,
36  * status, length of the buffer being pointed to and the pointer to the next
37  * entry. Length of the buffer is in number of bytes. Interrupt will be
38  * triggered each time a entry is processed by hardware.
39  *
40  * System power management is not yet supported by the driver.
41  *
42  * 	NOTE:
43  * 	This driver depends on the misc/ac97 and drv/audio modules being
44  *	loaded first.
45  */
46 #include <sys/types.h>
47 #include <sys/modctl.h>
48 #include <sys/kmem.h>
49 #include <sys/conf.h>
50 #include <sys/ddi.h>
51 #include <sys/sunddi.h>
52 #include <sys/pci.h>
53 #include <sys/note.h>
54 #include <sys/audio/audio_driver.h>
55 #include <sys/audio/ac97.h>
56 #include "audioixp.h"
57 
58 /*
59  * Module linkage routines for the kernel
60  */
61 static int audioixp_ddi_attach(dev_info_t *, ddi_attach_cmd_t);
62 static int audioixp_ddi_detach(dev_info_t *, ddi_detach_cmd_t);
63 static int audioixp_quiesce(dev_info_t *);
64 static int audioixp_resume(dev_info_t *);
65 static int audioixp_suspend(dev_info_t *);
66 
67 /*
68  * Entry point routine prototypes
69  */
70 static int audioixp_open(void *, int, unsigned *, unsigned *, caddr_t *);
71 static void audioixp_close(void *);
72 static int audioixp_start(void *);
73 static void audioixp_stop(void *);
74 static int audioixp_format(void *);
75 static int audioixp_channels(void *);
76 static int audioixp_rate(void *);
77 static uint64_t audioixp_count(void *);
78 static void audioixp_sync(void *, unsigned);
79 static size_t audioixp_qlen(void *);
80 
81 static audio_engine_ops_t audioixp_engine_ops = {
82 	AUDIO_ENGINE_VERSION,
83 	audioixp_open,
84 	audioixp_close,
85 	audioixp_start,
86 	audioixp_stop,
87 	audioixp_count,
88 	audioixp_format,
89 	audioixp_channels,
90 	audioixp_rate,
91 	audioixp_sync,
92 	audioixp_qlen
93 };
94 
95 
96 /*
97  * interrupt handler
98  */
99 static uint_t	audioixp_intr(caddr_t);
100 
101 /*
102  * Local Routine Prototypes
103  */
104 static int audioixp_attach(dev_info_t *);
105 static int audioixp_detach(dev_info_t *);
106 static int audioixp_alloc_port(audioixp_state_t *, int);
107 static void audioixp_start_port(audioixp_port_t *);
108 static void audioixp_stop_port(audioixp_port_t *);
109 static void audioixp_reset_port(audioixp_port_t *);
110 static void audioixp_update_port(audioixp_port_t *);
111 
112 static int audioixp_codec_sync(audioixp_state_t *);
113 static void audioixp_wr97(void *, uint8_t, uint16_t);
114 static uint16_t audioixp_rd97(void *, uint8_t);
115 static int audioixp_reset_ac97(audioixp_state_t *);
116 static int audioixp_map_regs(audioixp_state_t *);
117 static void audioixp_unmap_regs(audioixp_state_t *);
118 static int audioixp_chip_init(audioixp_state_t *);
119 static void audioixp_destroy(audioixp_state_t *);
120 
121 /*
122  * Global variables, but used only by this file.
123  */
124 
125 /*
126  * DDI Structures
127  */
128 
129 /* Device operations structure */
130 static struct dev_ops audioixp_dev_ops = {
131 	DEVO_REV,		/* devo_rev */
132 	0,			/* devo_refcnt */
133 	NULL,			/* devo_getinfo */
134 	nulldev,		/* devo_identify - obsolete */
135 	nulldev,		/* devo_probe */
136 	audioixp_ddi_attach,	/* devo_attach */
137 	audioixp_ddi_detach,	/* devo_detach */
138 	nodev,			/* devo_reset */
139 	NULL,			/* devi_cb_ops */
140 	NULL,			/* devo_bus_ops */
141 	NULL,			/* devo_power */
142 	audioixp_quiesce,	/* devo_quiesce */
143 };
144 
145 /* Linkage structure for loadable drivers */
146 static struct modldrv audioixp_modldrv = {
147 	&mod_driverops,		/* drv_modops */
148 	IXP_MOD_NAME,		/* drv_linkinfo */
149 	&audioixp_dev_ops,	/* drv_dev_ops */
150 };
151 
152 /* Module linkage structure */
153 static struct modlinkage audioixp_modlinkage = {
154 	MODREV_1,			/* ml_rev */
155 	(void *)&audioixp_modldrv,	/* ml_linkage */
156 	NULL				/* NULL terminates the list */
157 };
158 
159 /*
160  * device access attributes for register mapping
161  */
162 static struct ddi_device_acc_attr dev_attr = {
163 	DDI_DEVICE_ATTR_V0,
164 	DDI_STRUCTURE_LE_ACC,
165 	DDI_STRICTORDER_ACC
166 };
167 static struct ddi_device_acc_attr buf_attr = {
168 	DDI_DEVICE_ATTR_V0,
169 	DDI_NEVERSWAP_ACC,
170 	DDI_STRICTORDER_ACC
171 };
172 
173 /*
174  * DMA attributes of buffer descriptor list
175  */
176 static ddi_dma_attr_t	bdlist_dma_attr = {
177 	DMA_ATTR_V0,	/* version */
178 	0,		/* addr_lo */
179 	0xffffffff,	/* addr_hi */
180 	0x0000ffff,	/* count_max */
181 	8,		/* align, BDL must be aligned on a 8-byte boundary */
182 	0x3c,		/* burstsize */
183 	8,		/* minxfer, set to the size of a BDlist entry */
184 	0x0000ffff,	/* maxxfer */
185 	0x00000fff,	/* seg, set to the RAM pagesize of intel platform */
186 	1,		/* sgllen, there's no scatter-gather list */
187 	8,		/* granular, set to the value of minxfer */
188 	0		/* flags, use virtual address */
189 };
190 
191 /*
192  * DMA attributes of buffers to be used to receive/send audio data
193  */
194 static ddi_dma_attr_t	sample_buf_dma_attr = {
195 	DMA_ATTR_V0,
196 	0,		/* addr_lo */
197 	0xffffffff,	/* addr_hi */
198 	0x0001fffe,	/* count_max */
199 	4,		/* align, data buffer is aligned on a 2-byte boundary */
200 	0x3c,		/* burstsize */
201 	4,		/* minxfer, set to the size of a sample data */
202 	0x0001ffff,	/* maxxfer */
203 	0x0001ffff,	/* seg */
204 	1,		/* sgllen, no scatter-gather */
205 	4,		/* granular, set to the value of minxfer */
206 	0,		/* flags, use virtual address */
207 };
208 
209 /*
210  * _init()
211  *
212  * Description:
213  *	Driver initialization, called when driver is first loaded.
214  *	This is how access is initially given to all the static structures.
215  *
216  * Arguments:
217  *	None
218  *
219  * Returns:
220  *	ddi_soft_state_init() status, see ddi_soft_state_init(9f), or
221  *	mod_install() status, see mod_install(9f)
222  */
223 int
224 _init(void)
225 {
226 	int	error;
227 
228 	audio_init_ops(&audioixp_dev_ops, IXP_NAME);
229 
230 	if ((error = mod_install(&audioixp_modlinkage)) != 0) {
231 		audio_fini_ops(&audioixp_dev_ops);
232 	}
233 
234 	return (error);
235 }
236 
237 /*
238  * _fini()
239  *
240  * Description:
241  *	Module de-initialization, called when the driver is to be unloaded.
242  *
243  * Arguments:
244  *	None
245  *
246  * Returns:
247  *	mod_remove() status, see mod_remove(9f)
248  */
249 int
250 _fini(void)
251 {
252 	int		error;
253 
254 	if ((error = mod_remove(&audioixp_modlinkage)) != 0) {
255 		return (error);
256 	}
257 
258 	audio_fini_ops(&audioixp_dev_ops);
259 
260 	return (0);
261 }
262 
263 /*
264  * _info()
265  *
266  * Description:
267  *	Module information, returns information about the driver.
268  *
269  * Arguments:
270  *	modinfo		*modinfop	Pointer to the opaque modinfo structure
271  *
272  * Returns:
273  *	mod_info() status, see mod_info(9f)
274  */
275 int
276 _info(struct modinfo *modinfop)
277 {
278 	return (mod_info(&audioixp_modlinkage, modinfop));
279 }
280 
281 
282 /* ******************* Driver Entry Points ********************************* */
283 
284 /*
285  * audioixp_ddi_attach()
286  *
287  * Description:
288  *	Attach an instance of the audioixp driver.
289  *
290  * Arguments:
291  *	dev_info_t	*dip	Pointer to the device's dev_info struct
292  *	ddi_attach_cmd_t cmd	Attach command
293  *
294  * Returns:
295  *	DDI_SUCCESS		The driver was initialized properly
296  *	DDI_FAILURE		The driver couldn't be initialized properly
297  */
298 static int
299 audioixp_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
300 {
301 	switch (cmd) {
302 	case DDI_ATTACH:
303 		return (audioixp_attach(dip));
304 
305 	/*
306 	 * now, no suspend/resume supported. we'll do it in the future.
307 	 */
308 	case DDI_RESUME:
309 		return (audioixp_resume(dip));
310 	default:
311 		return (DDI_FAILURE);
312 	}
313 }
314 
315 /*
316  * audioixp_ddi_detach()
317  *
318  * Description:
319  *	Detach an instance of the audioixp driver.
320  *
321  * Arguments:
322  *	dev_info_t		*dip	Pointer to the device's dev_info struct
323  *	ddi_detach_cmd_t	cmd	Detach command
324  *
325  * Returns:
326  *	DDI_SUCCESS	The driver was detached
327  *	DDI_FAILURE	The driver couldn't be detached
328  */
329 static int
330 audioixp_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
331 {
332 	switch (cmd) {
333 	case DDI_DETACH:
334 		return (audioixp_detach(dip));
335 
336 	/*
337 	 * now, no suspend/resume supported. we'll do it in the future.
338 	 */
339 	case DDI_SUSPEND:
340 		return (audioixp_suspend(dip));
341 
342 	default:
343 		return (DDI_FAILURE);
344 	}
345 }
346 
347 static void
348 audioixp_stop_dma(audioixp_state_t *statep)
349 {
350 	CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA);
351 	CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA);
352 }
353 
354 static void
355 audioixp_disable_intr(audioixp_state_t *statep)
356 {
357 	PUT32(IXP_AUDIO_INT, GET32(IXP_AUDIO_INT));
358 	PUT32(IXP_AUDIO_INT_EN, 0);
359 }
360 
361 /*
362  * quiesce(9E) entry point.
363  *
364  * This function is called when the system is single-threaded at high
365  * PIL with preemption disabled. Therefore, this function must not be blocked.
366  *
367  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
368  * DDI_FAILURE indicates an error condition and should almost never happen.
369  */
370 static int
371 audioixp_quiesce(dev_info_t *dip)
372 {
373 	audioixp_state_t		*statep;
374 
375 	statep = ddi_get_driver_private(dip);
376 	ASSERT(statep != NULL);
377 
378 	/* disable HW interrupt */
379 	audioixp_disable_intr(statep);
380 
381 	/* stop DMA engines */
382 	audioixp_stop_dma(statep);
383 
384 	return (DDI_SUCCESS);
385 }
386 
387 static int
388 audioixp_suspend(dev_info_t *dip)
389 {
390 	audioixp_state_t		*statep;
391 
392 	statep = ddi_get_driver_private(dip);
393 	ASSERT(statep != NULL);
394 
395 	ac97_suspend(statep->ac97);
396 	mutex_enter(&statep->inst_lock);
397 
398 	statep->suspended = B_TRUE;
399 
400 	audioixp_disable_intr(statep);
401 	audioixp_stop_dma(statep);
402 
403 	mutex_exit(&statep->inst_lock);
404 	return (DDI_SUCCESS);
405 }
406 
407 static void
408 audioixp_resume_port(audioixp_port_t *port)
409 {
410 	if (port != NULL) {
411 		if (port->engine != NULL) {
412 			audio_engine_reset(port->engine);
413 		}
414 	}
415 	audioixp_reset_port(port);
416 	if (port->started) {
417 		audioixp_start_port(port);
418 	} else {
419 		audioixp_stop_port(port);
420 	}
421 }
422 
423 static int
424 audioixp_resume(dev_info_t *dip)
425 {
426 	audioixp_state_t		*statep;
427 	audio_dev_t			*adev;
428 	audioixp_port_t			*rec_port, *play_port;
429 
430 	statep = ddi_get_driver_private(dip);
431 	adev = statep->adev;
432 	ASSERT(statep != NULL);
433 
434 	if (audioixp_chip_init(statep) != DDI_SUCCESS) {
435 		audio_dev_warn(adev, "DDI_RESUME failed to init chip");
436 		return (DDI_SUCCESS);
437 	}
438 
439 	ac97_resume(statep->ac97);
440 	mutex_enter(&statep->inst_lock);
441 	statep->suspended = B_FALSE;
442 
443 	rec_port = statep->rec_port;
444 	play_port = statep->play_port;
445 
446 	audioixp_resume_port(rec_port);
447 	audioixp_resume_port(play_port);
448 
449 	mutex_exit(&statep->inst_lock);
450 	return (DDI_SUCCESS);
451 }
452 /*
453  * audioixp_intr()
454  *
455  * Description:
456  *	Interrupt service routine for both play and record. For play we
457  *	get the next buffers worth of audio. For record we send it on to
458  *	the mixer.
459  *
460  *	There's a hardware pointer which indicate memory location where
461  *	the hardware is processing. We check this pointer to decide whether
462  *	to handle the buffer and how many buffers should be handled.
463  *	Refer to ATI IXP400/450 Register Reference Manual, page 193,194.
464  *
465  * Arguments:
466  *	caddr_t		arg	Pointer to the interrupting device's state
467  *				structure
468  *
469  * Returns:
470  *	DDI_INTR_CLAIMED	Interrupt claimed and processed
471  *	DDI_INTR_UNCLAIMED	Interrupt not claimed, and thus ignored
472  */
473 static uint_t
474 audioixp_intr(caddr_t arg)
475 {
476 	audioixp_state_t	*statep;
477 	uint32_t		sr;
478 	int			claimed = DDI_INTR_UNCLAIMED;
479 
480 	statep = (void *)arg;
481 	mutex_enter(&statep->inst_lock);
482 
483 	sr = GET32(IXP_AUDIO_INT);
484 
485 	/* PCM in interrupt */
486 	if (sr & IXP_AUDIO_INT_IN_DMA) {
487 		claimed = DDI_INTR_CLAIMED;
488 		PUT32(IXP_AUDIO_INT, IXP_AUDIO_INT_IN_DMA);
489 	}
490 
491 	/* PCM out interrupt */
492 	if (sr & IXP_AUDIO_INT_OUT_DMA) {
493 		claimed = DDI_INTR_CLAIMED;
494 		PUT32(IXP_AUDIO_INT, IXP_AUDIO_INT_OUT_DMA);
495 	}
496 
497 	/* system is too busy to process the input stream, ignore it */
498 	if (sr & IXP_AUDIO_INT_IN_DMA_OVERFLOW) {
499 		claimed = DDI_INTR_CLAIMED;
500 		PUT32(IXP_AUDIO_INT, IXP_AUDIO_INT_IN_DMA_OVERFLOW);
501 	}
502 
503 	/* System is too busy, ignore it */
504 	if (sr & IXP_AUDIO_INT_OUT_DMA_UNDERFLOW) {
505 		claimed = DDI_INTR_CLAIMED;
506 		PUT32(IXP_AUDIO_INT, IXP_AUDIO_INT_OUT_DMA_UNDERFLOW);
507 	}
508 
509 	/* update the kernel interrupt statistics */
510 	if ((claimed == DDI_INTR_CLAIMED) && statep->ksp) {
511 		IXP_KIOP(statep)->intrs[KSTAT_INTR_HARD]++;
512 	}
513 
514 	mutex_exit(&statep->inst_lock);
515 
516 	if (sr & IXP_AUDIO_INT_IN_DMA) {
517 		audio_engine_produce(statep->rec_port->engine);
518 	}
519 	if (sr & IXP_AUDIO_INT_OUT_DMA) {
520 		audio_engine_consume(statep->play_port->engine);
521 	}
522 
523 	return (claimed);
524 }
525 
526 /*
527  * audioixp_open()
528  *
529  * Description:
530  *	Opens a DMA engine for use.
531  *
532  * Arguments:
533  *	void		*arg		The DMA engine to set up
534  *	int		flag		Open flags
535  *	unsigned	*fragfrp	Receives number of frames per fragment
536  *	unsigned	*nfragsp	Receives number of fragments
537  *	caddr_t		*bufp		Receives kernel data buffer
538  *
539  * Returns:
540  *	0	on success
541  *	errno	on failure
542  */
543 static int
544 audioixp_open(void *arg, int flag,
545     unsigned *fragfrp, unsigned *nfragsp, caddr_t *bufp)
546 {
547 	audioixp_port_t	*port = arg;
548 
549 	_NOTE(ARGUNUSED(flag));
550 
551 	port->started = B_FALSE;
552 	port->count = 0;
553 	port->offset = 0;
554 	*fragfrp = port->fragfr;
555 	*nfragsp = IXP_BD_NUMS;
556 	*bufp = port->samp_kaddr;
557 
558 	mutex_enter(&port->statep->inst_lock);
559 	audioixp_reset_port(port);
560 	mutex_exit(&port->statep->inst_lock);
561 
562 	return (0);
563 }
564 
565 /*
566  * audioixp_close()
567  *
568  * Description:
569  *	Closes an audio DMA engine that was previously opened.  Since
570  *	nobody is using it, we take this opportunity to possibly power
571  *	down the entire device.
572  *
573  * Arguments:
574  *	void	*arg		The DMA engine to shut down
575  */
576 static void
577 audioixp_close(void *arg)
578 {
579 	audioixp_port_t		*port = arg;
580 	audioixp_state_t	*statep = port->statep;
581 
582 	mutex_enter(&statep->inst_lock);
583 	audioixp_stop_port(port);
584 	port->started = B_FALSE;
585 	mutex_exit(&statep->inst_lock);
586 }
587 
588 /*
589  * audioixp_stop()
590  *
591  * Description:
592  *	This is called by the framework to stop a port that is
593  *	transferring data.
594  *
595  * Arguments:
596  *	void	*arg		The DMA engine to stop
597  */
598 static void
599 audioixp_stop(void *arg)
600 {
601 	audioixp_port_t		*port = arg;
602 	audioixp_state_t	*statep = port->statep;
603 
604 	mutex_enter(&statep->inst_lock);
605 	if (port->started) {
606 		audioixp_stop_port(port);
607 	}
608 	port->started = B_FALSE;
609 	mutex_exit(&statep->inst_lock);
610 }
611 
612 /*
613  * audioixp_start()
614  *
615  * Description:
616  *	This is called by the framework to start a port transferring data.
617  *
618  * Arguments:
619  *	void	*arg		The DMA engine to start
620  *
621  * Returns:
622  *	0 	on success (never fails, errno if it did)
623  */
624 static int
625 audioixp_start(void *arg)
626 {
627 	audioixp_port_t		*port = arg;
628 	audioixp_state_t	*statep = port->statep;
629 
630 	mutex_enter(&statep->inst_lock);
631 	if (!port->started) {
632 		audioixp_start_port(port);
633 		port->started = B_TRUE;
634 	}
635 	mutex_exit(&statep->inst_lock);
636 	return (0);
637 }
638 
639 /*
640  * audioixp_format()
641  *
642  * Description:
643  *	This is called by the framework to query the format for the device.
644  *
645  * Arguments:
646  *	void	*arg		The DMA engine to query
647  *
648  * Returns:
649  *	AUDIO_FORMAT_S16_LE
650  */
651 static int
652 audioixp_format(void *arg)
653 {
654 	_NOTE(ARGUNUSED(arg));
655 
656 	return (AUDIO_FORMAT_S16_LE);
657 }
658 
659 /*
660  * audioixp_channels()
661  *
662  * Description:
663  *	This is called by the framework to query the channels for the device.
664  *
665  * Arguments:
666  *	void	*arg		The DMA engine to query
667  *
668  * Returns:
669  *	Number of channels for the device.
670  */
671 static int
672 audioixp_channels(void *arg)
673 {
674 	audioixp_port_t *port = arg;
675 
676 	return (port->nchan);
677 }
678 
679 /*
680  * audioixp_rate()
681  *
682  * Description:
683  *	This is called by the framework to query the rate of the device.
684  *
685  * Arguments:
686  *	void	*arg		The DMA engine to query
687  *
688  * Returns:
689  *	48000
690  */
691 static int
692 audioixp_rate(void *arg)
693 {
694 	_NOTE(ARGUNUSED(arg));
695 
696 	return (48000);
697 }
698 
699 /*
700  * audioixp_count()
701  *
702  * Description:
703  *	This is called by the framework to get the engine's frame counter
704  *
705  * Arguments:
706  *	void	*arg		The DMA engine to query
707  *
708  * Returns:
709  *	frame count for current engine
710  */
711 static uint64_t
712 audioixp_count(void *arg)
713 {
714 	audioixp_port_t		*port = arg;
715 	audioixp_state_t	*statep = port->statep;
716 	uint64_t		val;
717 
718 	mutex_enter(&statep->inst_lock);
719 	audioixp_update_port(port);
720 	val = port->count;
721 	mutex_exit(&statep->inst_lock);
722 
723 	return (val);
724 }
725 
726 /*
727  * audioixp_sync()
728  *
729  * Description:
730  *	This is called by the framework to synchronize DMA caches.
731  *
732  * Arguments:
733  *	void	*arg		The DMA engine to sync
734  */
735 static void
736 audioixp_sync(void *arg, unsigned nframes)
737 {
738 	audioixp_port_t *port = arg;
739 	_NOTE(ARGUNUSED(nframes));
740 
741 	(void) ddi_dma_sync(port->samp_dmah, 0, 0, port->sync_dir);
742 }
743 
744 /*
745  * audioixp_qlen()
746  *
747  * Description:
748  *	This is called by the framework to determine on-device queue length.
749  *
750  * Arguments:
751  *	void	*arg		The DMA engine to query
752  *
753  * Returns:
754  *	hardware queue length not reported by count (0 for this device)
755  */
756 static size_t
757 audioixp_qlen(void *arg)
758 {
759 	_NOTE(ARGUNUSED(arg));
760 	return (0);
761 }
762 
763 
764 /* *********************** Local Routines *************************** */
765 
766 /*
767  * audioixp_alloc_port()
768  *
769  * Description:
770  *	This routine allocates the DMA handles and the memory for the
771  *	DMA engines to use.  It also configures the BDL lists properly
772  *	for use.
773  *
774  * Arguments:
775  *	dev_info_t	*dip	Pointer to the device's devinfo
776  *
777  * Returns:
778  *	DDI_SUCCESS		Registers successfully mapped
779  *	DDI_FAILURE		Registers not successfully mapped
780  */
781 static int
782 audioixp_alloc_port(audioixp_state_t *statep, int num)
783 {
784 	ddi_dma_cookie_t	cookie;
785 	uint_t			count;
786 	int			dir;
787 	unsigned		caps;
788 	char			*prop;
789 	audio_dev_t		*adev;
790 	audioixp_port_t		*port;
791 	uint32_t		paddr;
792 	int			rc;
793 	dev_info_t		*dip;
794 	audioixp_bd_entry_t	*bdentry;
795 
796 	adev = statep->adev;
797 	dip = statep->dip;
798 
799 	port = kmem_zalloc(sizeof (*port), KM_SLEEP);
800 	port->statep = statep;
801 	port->started = B_FALSE;
802 	port->num = num;
803 
804 	switch (num) {
805 	case IXP_REC:
806 		statep->rec_port = port;
807 		prop = "record-interrupts";
808 		dir = DDI_DMA_READ;
809 		caps = ENGINE_INPUT_CAP;
810 		port->sync_dir = DDI_DMA_SYNC_FORKERNEL;
811 		port->nchan = 2;
812 		break;
813 	case IXP_PLAY:
814 		statep->play_port = port;
815 		prop = "play-interrupts";
816 		dir = DDI_DMA_WRITE;
817 		caps = ENGINE_OUTPUT_CAP;
818 		port->sync_dir = DDI_DMA_SYNC_FORDEV;
819 		/* This could possibly be conditionalized */
820 		port->nchan = 6;
821 		break;
822 	default:
823 		audio_dev_warn(adev, "bad port number (%d)!", num);
824 		return (DDI_FAILURE);
825 	}
826 
827 	port->intrs = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
828 	    DDI_PROP_DONTPASS, prop, IXP_INTS);
829 
830 	/* make sure the values are good */
831 	if (port->intrs < IXP_MIN_INTS) {
832 		audio_dev_warn(adev, "%s too low, %d, resetting to %d",
833 		    prop, port->intrs, IXP_INTS);
834 		port->intrs = IXP_INTS;
835 	} else if (port->intrs > IXP_MAX_INTS) {
836 		audio_dev_warn(adev, "%s too high, %d, resetting to %d",
837 		    prop, port->intrs, IXP_INTS);
838 		port->intrs = IXP_INTS;
839 	}
840 
841 	/*
842 	 * Figure out how much space we need.  Sample rate is 48kHz, and
843 	 * we need to store 8 chunks.  (Note that this means that low
844 	 * interrupt frequencies will require more RAM.)
845 	 */
846 	port->fragfr = 48000 / port->intrs;
847 	port->fragfr = IXP_ROUNDUP(port->fragfr, IXP_MOD_SIZE);
848 	port->fragsz = port->fragfr * port->nchan * 2;
849 	port->samp_size = port->fragsz * IXP_BD_NUMS;
850 
851 	/* allocate dma handle */
852 	rc = ddi_dma_alloc_handle(dip, &sample_buf_dma_attr, DDI_DMA_SLEEP,
853 	    NULL, &port->samp_dmah);
854 	if (rc != DDI_SUCCESS) {
855 		audio_dev_warn(adev, "ddi_dma_alloc_handle failed: %d", rc);
856 		return (DDI_FAILURE);
857 	}
858 	/* allocate DMA buffer */
859 	rc = ddi_dma_mem_alloc(port->samp_dmah, port->samp_size, &buf_attr,
860 	    DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &port->samp_kaddr,
861 	    &port->samp_size, &port->samp_acch);
862 	if (rc == DDI_FAILURE) {
863 		audio_dev_warn(adev, "dma_mem_alloc failed");
864 		return (DDI_FAILURE);
865 	}
866 
867 	/* bind DMA buffer */
868 	rc = ddi_dma_addr_bind_handle(port->samp_dmah, NULL,
869 	    port->samp_kaddr, port->samp_size, dir|DDI_DMA_CONSISTENT,
870 	    DDI_DMA_SLEEP, NULL, &cookie, &count);
871 	if ((rc != DDI_DMA_MAPPED) || (count != 1)) {
872 		audio_dev_warn(adev,
873 		    "ddi_dma_addr_bind_handle failed: %d", rc);
874 		return (DDI_FAILURE);
875 	}
876 	port->samp_paddr = cookie.dmac_address;
877 
878 	/*
879 	 * now, from here we allocate DMA memory for buffer descriptor list.
880 	 * we allocate adjacent DMA memory for all DMA engines.
881 	 */
882 	rc = ddi_dma_alloc_handle(dip, &bdlist_dma_attr, DDI_DMA_SLEEP,
883 	    NULL, &port->bdl_dmah);
884 	if (rc != DDI_SUCCESS) {
885 		audio_dev_warn(adev, "ddi_dma_alloc_handle(bdlist) failed");
886 		return (DDI_FAILURE);
887 	}
888 
889 	/*
890 	 * we allocate all buffer descriptors lists in continuous dma memory.
891 	 */
892 	port->bdl_size = sizeof (audioixp_bd_entry_t) * IXP_BD_NUMS;
893 	rc = ddi_dma_mem_alloc(port->bdl_dmah, port->bdl_size,
894 	    &dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
895 	    &port->bdl_kaddr, &port->bdl_size, &port->bdl_acch);
896 	if (rc != DDI_SUCCESS) {
897 		audio_dev_warn(adev, "ddi_dma_mem_alloc(bdlist) failed");
898 		return (DDI_FAILURE);
899 	}
900 
901 	rc = ddi_dma_addr_bind_handle(port->bdl_dmah, NULL, port->bdl_kaddr,
902 	    port->bdl_size, DDI_DMA_WRITE|DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
903 	    NULL, &cookie, &count);
904 	if ((rc != DDI_DMA_MAPPED) || (count != 1)) {
905 		audio_dev_warn(adev, "addr_bind_handle failed");
906 		return (DDI_FAILURE);
907 	}
908 	port->bdl_paddr = cookie.dmac_address;
909 
910 	/*
911 	 * Wire up the BD list.
912 	 */
913 	paddr = port->samp_paddr;
914 	bdentry = (void *)port->bdl_kaddr;
915 
916 	for (int i = 0; i < IXP_BD_NUMS; i++) {
917 
918 		/* set base address of buffer */
919 		ddi_put32(port->bdl_acch, &bdentry->buf_base, paddr);
920 		ddi_put16(port->bdl_acch, &bdentry->status, 0);
921 		ddi_put16(port->bdl_acch, &bdentry->buf_len, port->fragsz / 4);
922 		ddi_put32(port->bdl_acch, &bdentry->next, port->bdl_paddr +
923 		    (((i + 1) % IXP_BD_NUMS) * sizeof (audioixp_bd_entry_t)));
924 		paddr += port->fragsz;
925 		bdentry++;
926 	}
927 	(void) ddi_dma_sync(port->bdl_dmah, 0, 0, DDI_DMA_SYNC_FORDEV);
928 
929 	port->engine = audio_engine_alloc(&audioixp_engine_ops, caps);
930 	if (port->engine == NULL) {
931 		audio_dev_warn(adev, "audio_engine_alloc failed");
932 		return (DDI_FAILURE);
933 	}
934 
935 	audio_engine_set_private(port->engine, port);
936 	audio_dev_add_engine(adev, port->engine);
937 
938 	return (DDI_SUCCESS);
939 }
940 
941 /*
942  * audioixp_free_port()
943  *
944  * Description:
945  *	This routine unbinds the DMA cookies, frees the DMA buffers,
946  *	deallocates the DMA handles.
947  *
948  * Arguments:
949  *	audioixp_port_t	*port	The port structure for a DMA engine.
950  */
951 static void
952 audioixp_free_port(audioixp_port_t *port)
953 {
954 	if (port == NULL)
955 		return;
956 
957 	if (port->engine) {
958 		audio_dev_remove_engine(port->statep->adev, port->engine);
959 		audio_engine_free(port->engine);
960 	}
961 	if (port->bdl_paddr) {
962 		(void) ddi_dma_unbind_handle(port->bdl_dmah);
963 	}
964 	if (port->bdl_acch) {
965 		ddi_dma_mem_free(&port->bdl_acch);
966 	}
967 	if (port->bdl_dmah) {
968 		ddi_dma_free_handle(&port->bdl_dmah);
969 	}
970 	if (port->samp_paddr) {
971 		(void) ddi_dma_unbind_handle(port->samp_dmah);
972 	}
973 	if (port->samp_acch) {
974 		ddi_dma_mem_free(&port->samp_acch);
975 	}
976 	if (port->samp_dmah) {
977 		ddi_dma_free_handle(&port->samp_dmah);
978 	}
979 	kmem_free(port, sizeof (*port));
980 }
981 
982 /*
983  * audioixp_start_port()
984  *
985  * Description:
986  *	This routine starts the DMA engine.
987  *
988  * Arguments:
989  *	audioixp_port_t	*port		Port of DMA engine to start.
990  */
991 static void
992 audioixp_start_port(audioixp_port_t *port)
993 {
994 	audioixp_state_t	*statep = port->statep;
995 
996 	ASSERT(mutex_owned(&statep->inst_lock));
997 
998 	/* if suspended, then do nothing else */
999 	if (statep->suspended) {
1000 		return;
1001 	}
1002 
1003 	if (port->num == IXP_REC) {
1004 		SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN);
1005 	} else {
1006 		SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT);
1007 	}
1008 }
1009 
1010 /*
1011  * audioixp_stop_port()
1012  *
1013  * Description:
1014  *	This routine stops the DMA engine.
1015  *
1016  * Arguments:
1017  *	audioixp_port_t	*port		Port of DMA engine to stop.
1018  */
1019 static void
1020 audioixp_stop_port(audioixp_port_t *port)
1021 {
1022 	audioixp_state_t	*statep = port->statep;
1023 
1024 	ASSERT(mutex_owned(&statep->inst_lock));
1025 
1026 	/* if suspended, then do nothing else */
1027 	if (statep->suspended) {
1028 		return;
1029 	}
1030 	if (port->num == IXP_REC) {
1031 		CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN);
1032 	} else {
1033 		CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT);
1034 	}
1035 }
1036 
1037 /*
1038  * audioixp_reset_port()
1039  *
1040  * Description:
1041  *	This routine resets the DMA engine pareparing it for work.
1042  *
1043  * Arguments:
1044  *	audioixp_port_t	*port		Port of DMA engine to reset.
1045  */
1046 static void
1047 audioixp_reset_port(audioixp_port_t *port)
1048 {
1049 	audioixp_state_t	*statep = port->statep;
1050 
1051 	ASSERT(mutex_owned(&statep->inst_lock));
1052 
1053 	/*
1054 	 * XXX: reset counters.
1055 	 */
1056 	port->count = 0;
1057 
1058 	if (statep->suspended)
1059 		return;
1060 
1061 	/*
1062 	 * Perform full reset of the engine, and enable its interrupts
1063 	 * but leave it turned off.
1064 	 */
1065 	if (port->num == IXP_REC) {
1066 		PUT32(IXP_AUDIO_FIFO_FLUSH, IXP_AUDIO_FIFO_FLUSH_IN);
1067 		SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_INTER_IN);
1068 
1069 		SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA);
1070 		PUT32(IXP_AUDIO_IN_DMA_LINK_P,
1071 		    port->bdl_paddr | IXP_AUDIO_IN_DMA_LINK_P_EN);
1072 
1073 	} else {
1074 		uint32_t slot = GET32(IXP_AUDIO_OUT_DMA_SLOT_EN_THRESHOLD);
1075 		PUT32(IXP_AUDIO_FIFO_FLUSH, IXP_AUDIO_FIFO_FLUSH_OUT);
1076 		/* clear all slots */
1077 		slot &= ~ (IXP_AUDIO_OUT_DMA_SLOT_3 |
1078 		    IXP_AUDIO_OUT_DMA_SLOT_4 |
1079 		    IXP_AUDIO_OUT_DMA_SLOT_5 |
1080 		    IXP_AUDIO_OUT_DMA_SLOT_6 |
1081 		    IXP_AUDIO_OUT_DMA_SLOT_7 |
1082 		    IXP_AUDIO_OUT_DMA_SLOT_8 |
1083 		    IXP_AUDIO_OUT_DMA_SLOT_9 |
1084 		    IXP_AUDIO_OUT_DMA_SLOT_10 |
1085 		    IXP_AUDIO_OUT_DMA_SLOT_11 |
1086 		    IXP_AUDIO_OUT_DMA_SLOT_12);
1087 		/* enable 6 channel out, unconditional for now */
1088 		slot |= IXP_AUDIO_OUT_DMA_SLOT_3 |
1089 		    IXP_AUDIO_OUT_DMA_SLOT_4 |
1090 		    IXP_AUDIO_OUT_DMA_SLOT_6 |
1091 		    IXP_AUDIO_OUT_DMA_SLOT_9 |
1092 		    IXP_AUDIO_OUT_DMA_SLOT_7 |
1093 		    IXP_AUDIO_OUT_DMA_SLOT_8;
1094 
1095 		PUT32(IXP_AUDIO_OUT_DMA_SLOT_EN_THRESHOLD, slot);
1096 
1097 		SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_INTER_OUT);
1098 
1099 		SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA);
1100 		PUT32(IXP_AUDIO_OUT_DMA_LINK_P,
1101 		    port->bdl_paddr | IXP_AUDIO_OUT_DMA_LINK_P_EN);
1102 	}
1103 }
1104 
1105 /*
1106  * audioixp_update_port()
1107  *
1108  * Description:
1109  *	This routine updates the ports frame counter from hardware, and
1110  *	gracefully handles wraps.
1111  *
1112  * Arguments:
1113  *	audioixp_port_t	*port		The port to update.
1114  */
1115 static void
1116 audioixp_update_port(audioixp_port_t *port)
1117 {
1118 	audioixp_state_t	*statep = port->statep;
1119 	unsigned		regoff;
1120 	unsigned		n;
1121 	int			loop;
1122 	uint32_t		offset;
1123 	uint32_t		paddr;
1124 
1125 	if (statep->suspended) {
1126 		return;
1127 	}
1128 	if (port->num == IXP_REC) {
1129 		regoff = IXP_AUDIO_IN_DMA_DT_CUR;
1130 	} else {
1131 		regoff = IXP_AUDIO_OUT_DMA_DT_CUR;
1132 	}
1133 
1134 	/*
1135 	 * Apparently it may take several tries to get an update on the
1136 	 * position.  Is this a hardware bug?
1137 	 */
1138 	for (loop = 100; loop; loop--) {
1139 		paddr = GET32(regoff);
1140 
1141 		/* make sure address is reasonable */
1142 		if ((paddr < port->samp_paddr) ||
1143 		    (paddr >= (port->samp_paddr + port->samp_size))) {
1144 			continue;
1145 		}
1146 
1147 		offset = paddr - port->samp_paddr;
1148 
1149 		if (offset >= port->offset) {
1150 			n = offset - port->offset;
1151 		} else {
1152 			n = offset + (port->samp_size - port->offset);
1153 		}
1154 		port->offset = offset;
1155 		port->count += (n / (port->nchan * sizeof (uint16_t)));
1156 		return;
1157 	}
1158 
1159 	audio_dev_warn(statep->adev, "Unable to update count (h/w bug?)");
1160 }
1161 
1162 
1163 /*
1164  * audioixp_map_regs()
1165  *
1166  * Description:
1167  *	The registers are mapped in.
1168  *
1169  * Arguments:
1170  *	audioixp_state_t	*state		  The device's state structure
1171  *
1172  * Returns:
1173  *	DDI_SUCCESS		Registers successfully mapped
1174  *	DDI_FAILURE		Registers not successfully mapped
1175  */
1176 static int
1177 audioixp_map_regs(audioixp_state_t *statep)
1178 {
1179 	dev_info_t		*dip = statep->dip;
1180 
1181 	/* map PCI config space */
1182 	if (pci_config_setup(statep->dip, &statep->pcih) == DDI_FAILURE) {
1183 		audio_dev_warn(statep->adev, "unable to map PCI config space");
1184 		return (DDI_FAILURE);
1185 	}
1186 
1187 	/* map audio mixer register */
1188 	if ((ddi_regs_map_setup(dip, IXP_IO_AM_REGS, &statep->regsp, 0, 0,
1189 	    &dev_attr, &statep->regsh)) != DDI_SUCCESS) {
1190 		audio_dev_warn(statep->adev, "unable to map audio registers");
1191 		return (DDI_FAILURE);
1192 	}
1193 	return (DDI_SUCCESS);
1194 }
1195 
1196 /*
1197  * audioixp_unmap_regs()
1198  *
1199  * Description:
1200  *	This routine unmaps control registers.
1201  *
1202  * Arguments:
1203  *	audioixp_state_t	*state		The device's state structure
1204  */
1205 static void
1206 audioixp_unmap_regs(audioixp_state_t *statep)
1207 {
1208 	if (statep->regsh) {
1209 		ddi_regs_map_free(&statep->regsh);
1210 	}
1211 
1212 	if (statep->pcih) {
1213 		pci_config_teardown(&statep->pcih);
1214 	}
1215 }
1216 
1217 /*
1218  * audioixp_codec_ready()
1219  *
1220  * Description:
1221  *	This routine checks the state of codecs.  It checks the flag to confirm
1222  *	that primary codec is ready.
1223  *
1224  * Arguments:
1225  *	audioixp_state_t	*state		The device's state structure
1226  *
1227  * Returns:
1228  *	DDI_SUCCESS	 codec is ready
1229  *	DDI_FAILURE	 codec is not ready
1230  */
1231 static int
1232 audioixp_codec_ready(audioixp_state_t *statep)
1233 {
1234 	uint32_t	sr;
1235 
1236 	PUT32(IXP_AUDIO_INT, 0xffffffff);
1237 	drv_usecwait(1000);
1238 
1239 	sr = GET32(IXP_AUDIO_INT);
1240 	if (sr & IXP_AUDIO_INT_CODEC0_NOT_READY) {
1241 		PUT32(IXP_AUDIO_INT, IXP_AUDIO_INT_CODEC0_NOT_READY);
1242 		audio_dev_warn(statep->adev, "primary codec not ready");
1243 
1244 		return (DDI_FAILURE);
1245 	}
1246 	return (DDI_SUCCESS);
1247 }
1248 
1249 /*
1250  * audioixp_codec_sync()
1251  *
1252  * Description:
1253  *	Serialize access to the AC97 audio mixer registers.
1254  *
1255  * Arguments:
1256  *	audioixp_state_t	*state		The device's state structure
1257  *
1258  * Returns:
1259  *	DDI_SUCCESS		Ready for an I/O access to the codec
1260  *	DDI_FAILURE		An I/O access is currently in progress, can't
1261  *				perform another I/O access.
1262  */
1263 static int
1264 audioixp_codec_sync(audioixp_state_t *statep)
1265 {
1266 	int 		i;
1267 	uint32_t	cmd;
1268 
1269 	for (i = 0; i < 300; i++) {
1270 		cmd = GET32(IXP_AUDIO_OUT_PHY_ADDR_DATA);
1271 		if (!(cmd & IXP_AUDIO_OUT_PHY_EN)) {
1272 			return (DDI_SUCCESS);
1273 		}
1274 		drv_usecwait(10);
1275 	}
1276 
1277 	audio_dev_warn(statep->adev, "unable to synchronize codec");
1278 	return (DDI_FAILURE);
1279 }
1280 
1281 /*
1282  * audioixp_rd97()
1283  *
1284  * Description:
1285  *	Get the specific AC97 Codec register.
1286  *
1287  * Arguments:
1288  *	void		*arg		The device's state structure
1289  *	uint8_t		reg		AC97 register number
1290  *
1291  * Returns:
1292  *	Register value.
1293  */
1294 static uint16_t
1295 audioixp_rd97(void *arg, uint8_t reg)
1296 {
1297 	audioixp_state_t	*statep = arg;
1298 	uint32_t		value;
1299 	uint32_t		result;
1300 
1301 	if (audioixp_codec_sync(statep) != DDI_SUCCESS)
1302 		return (0xffff);
1303 
1304 	value = IXP_AUDIO_OUT_PHY_PRIMARY_CODEC |
1305 	    IXP_AUDIO_OUT_PHY_READ |
1306 	    IXP_AUDIO_OUT_PHY_EN |
1307 	    ((unsigned)reg << IXP_AUDIO_OUT_PHY_ADDR_SHIFT);
1308 	PUT32(IXP_AUDIO_OUT_PHY_ADDR_DATA, value);
1309 
1310 	if (audioixp_codec_sync(statep) != DDI_SUCCESS)
1311 		return (0xffff);
1312 
1313 	for (int i = 0; i < 300; i++) {
1314 		result = GET32(IXP_AUDIO_IN_PHY_ADDR_DATA);
1315 		if (result & IXP_AUDIO_IN_PHY_READY)	{
1316 			return (result >> IXP_AUDIO_IN_PHY_DATA_SHIFT);
1317 		}
1318 		drv_usecwait(10);
1319 	}
1320 
1321 done:
1322 	audio_dev_warn(statep->adev, "time out reading codec reg %d", reg);
1323 	return (0xffff);
1324 }
1325 
1326 /*
1327  * audioixp_wr97()
1328  *
1329  * Description:
1330  *	Set the specific AC97 Codec register.
1331  *
1332  * Arguments:
1333  *	void		*arg		The device's state structure
1334  *	uint8_t		reg		AC97 register number
1335  *	uint16_t	data		The data want to be set
1336  */
1337 static void
1338 audioixp_wr97(void *arg, uint8_t reg, uint16_t data)
1339 {
1340 	audioixp_state_t	*statep = arg;
1341 	uint32_t		value;
1342 
1343 	if (audioixp_codec_sync(statep) != DDI_SUCCESS) {
1344 		return;
1345 	}
1346 
1347 	value = IXP_AUDIO_OUT_PHY_PRIMARY_CODEC |
1348 	    IXP_AUDIO_OUT_PHY_WRITE |
1349 	    IXP_AUDIO_OUT_PHY_EN |
1350 	    ((unsigned)reg << IXP_AUDIO_OUT_PHY_ADDR_SHIFT) |
1351 	    ((unsigned)data << IXP_AUDIO_OUT_PHY_DATA_SHIFT);
1352 	PUT32(IXP_AUDIO_OUT_PHY_ADDR_DATA, value);
1353 
1354 	(void) audioixp_rd97(statep, reg);
1355 }
1356 
1357 /*
1358  * audioixp_reset_ac97()
1359  *
1360  * Description:
1361  *	Reset AC97 Codec register.
1362  *
1363  * Arguments:
1364  *	audioixp_state_t	*state		The device's state structure
1365  *
1366  * Returns:
1367  *	DDI_SUCCESS		Reset the codec successfully
1368  *	DDI_FAILURE		Failed to reset the codec
1369  */
1370 static int
1371 audioixp_reset_ac97(audioixp_state_t *statep)
1372 {
1373 	uint32_t	cmd;
1374 	int i;
1375 
1376 	CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_POWER_DOWN);
1377 	drv_usecwait(10);
1378 
1379 	/* register reset */
1380 	SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_AC_SOFT_RESET);
1381 	/* force a read to flush caches */
1382 	(void) GET32(IXP_AUDIO_CMD);
1383 
1384 	drv_usecwait(10);
1385 	CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_AC_SOFT_RESET);
1386 
1387 	/* cold reset */
1388 	for (i = 0; i < 300; i++) {
1389 		cmd = GET32(IXP_AUDIO_CMD);
1390 		if (cmd & IXP_AUDIO_CMD_AC_ACTIVE) {
1391 			cmd |= IXP_AUDIO_CMD_AC_RESET | IXP_AUDIO_CMD_AC_SYNC;
1392 			PUT32(IXP_AUDIO_CMD, cmd);
1393 			return (DDI_SUCCESS);
1394 		}
1395 		cmd &= ~IXP_AUDIO_CMD_AC_RESET;
1396 		cmd |= IXP_AUDIO_CMD_AC_SYNC;
1397 		PUT32(IXP_AUDIO_CMD, cmd);
1398 		(void) GET32(IXP_AUDIO_CMD);
1399 		drv_usecwait(10);
1400 		cmd |= IXP_AUDIO_CMD_AC_RESET;
1401 		PUT32(IXP_AUDIO_CMD, cmd);
1402 		drv_usecwait(10);
1403 	}
1404 
1405 	audio_dev_warn(statep->adev, "AC'97 reset timed out");
1406 	return (DDI_FAILURE);
1407 }
1408 
1409 /*
1410  * audioixp_chip_init()
1411  *
1412  * Description:
1413  *	This routine initializes ATI IXP audio controller and the AC97
1414  *	codec.
1415  *
1416  * Arguments:
1417  *	audioixp_state_t	*state		The device's state structure
1418  *
1419  * Returns:
1420  *	DDI_SUCCESS	The hardware was initialized properly
1421  *	DDI_FAILURE	The hardware couldn't be initialized properly
1422  */
1423 static int
1424 audioixp_chip_init(audioixp_state_t *statep)
1425 {
1426 	/*
1427 	 * put the audio controller into quiet state, everything off
1428 	 */
1429 	CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA);
1430 	CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA);
1431 
1432 	/* AC97 reset */
1433 	if (audioixp_reset_ac97(statep) != DDI_SUCCESS) {
1434 		audio_dev_warn(statep->adev, "AC97 codec reset failed");
1435 		return (DDI_FAILURE);
1436 	}
1437 
1438 	if (audioixp_codec_ready(statep) != DDI_SUCCESS) {
1439 		audio_dev_warn(statep->adev, "AC97 codec not ready");
1440 		return (DDI_FAILURE);
1441 	}
1442 
1443 	/* enable interrupts */
1444 	PUT32(IXP_AUDIO_INT, 0xffffffff);
1445 	PUT32(
1446 	    IXP_AUDIO_INT_EN,
1447 	    IXP_AUDIO_INT_EN_IN_DMA_OVERFLOW |
1448 	    IXP_AUDIO_INT_EN_STATUS |
1449 	    IXP_AUDIO_INT_EN_OUT_DMA_UNDERFLOW);
1450 	return (DDI_SUCCESS);
1451 
1452 }	/* audioixp_chip_init() */
1453 
1454 /*
1455  * audioixp_attach()
1456  *
1457  * Description:
1458  *	Attach an instance of the audioixp driver. This routine does
1459  * 	the device dependent attach tasks.
1460  *
1461  * Arguments:
1462  *	dev_info_t	*dip	Pointer to the device's dev_info struct
1463  *	ddi_attach_cmd_t cmd	Attach command
1464  *
1465  * Returns:
1466  *	DDI_SUCCESS		The driver was initialized properly
1467  *	DDI_FAILURE		The driver couldn't be initialized properly
1468  */
1469 static int
1470 audioixp_attach(dev_info_t *dip)
1471 {
1472 	uint16_t		cmdeg;
1473 	audioixp_state_t	*statep;
1474 	audio_dev_t		*adev;
1475 	uint32_t		devid;
1476 	const char		*name;
1477 	const char		*rev;
1478 
1479 	/* we don't support high level interrupts in the driver */
1480 	if (ddi_intr_hilevel(dip, 0) != 0) {
1481 		cmn_err(CE_WARN,
1482 		    "!%s%d: unsupported high level interrupt",
1483 		    ddi_driver_name(dip), ddi_get_instance(dip));
1484 		return (DDI_FAILURE);
1485 	}
1486 
1487 	/* allocate the soft state structure */
1488 	statep = kmem_zalloc(sizeof (*statep), KM_SLEEP);
1489 	statep->dip = dip;
1490 	ddi_set_driver_private(dip, statep);
1491 
1492 	if (ddi_get_iblock_cookie(dip, 0, &statep->iblock) != DDI_SUCCESS) {
1493 		cmn_err(CE_WARN,
1494 		    "!%s%d: cannot get iblock cookie",
1495 		    ddi_driver_name(dip), ddi_get_instance(dip));
1496 		kmem_free(statep, sizeof (*statep));
1497 		return (DDI_FAILURE);
1498 	}
1499 	mutex_init(&statep->inst_lock, NULL, MUTEX_DRIVER, statep->iblock);
1500 
1501 	/* allocate framework audio device */
1502 	if ((adev = audio_dev_alloc(dip, 0)) == NULL) {
1503 		cmn_err(CE_WARN, "!%s%d: unable to allocate audio dev",
1504 		    ddi_driver_name(dip), ddi_get_instance(dip));
1505 		goto error;
1506 	}
1507 	statep->adev = adev;
1508 
1509 	/* map in the registers */
1510 	if (audioixp_map_regs(statep) != DDI_SUCCESS) {
1511 		audio_dev_warn(adev, "couldn't map registers");
1512 		goto error;
1513 	}
1514 
1515 	/* set device information -- this could be smarter */
1516 	devid = ((pci_config_get16(statep->pcih, PCI_CONF_VENID)) << 16) |
1517 	    pci_config_get16(statep->pcih, PCI_CONF_DEVID);
1518 
1519 	name = "ATI AC'97";
1520 	switch (devid) {
1521 	case IXP_PCI_ID_200:
1522 		rev = "IXP150";
1523 		break;
1524 	case IXP_PCI_ID_300:
1525 		rev = "SB300";
1526 		break;
1527 	case IXP_PCI_ID_400:
1528 		if (pci_config_get8(statep->pcih, PCI_CONF_REVID) & 0x80) {
1529 			rev = "SB450";
1530 		} else {
1531 			rev = "SB400";
1532 		}
1533 		break;
1534 	case IXP_PCI_ID_SB600:
1535 		rev = "SB600";
1536 		break;
1537 	default:
1538 		rev = "Unknown";
1539 		break;
1540 	}
1541 	audio_dev_set_description(adev, name);
1542 	audio_dev_set_version(adev, rev);
1543 
1544 	/* allocate port structures */
1545 	if ((audioixp_alloc_port(statep, IXP_PLAY) != DDI_SUCCESS) ||
1546 	    (audioixp_alloc_port(statep, IXP_REC) != DDI_SUCCESS)) {
1547 		goto error;
1548 	}
1549 
1550 	statep->ac97 = ac97_alloc(dip, audioixp_rd97, audioixp_wr97, statep);
1551 	if (statep->ac97 == NULL) {
1552 		audio_dev_warn(adev, "failed to allocate ac97 handle");
1553 		goto error;
1554 	}
1555 
1556 	/* set PCI command register */
1557 	cmdeg = pci_config_get16(statep->pcih, PCI_CONF_COMM);
1558 	pci_config_put16(statep->pcih, PCI_CONF_COMM,
1559 	    cmdeg | PCI_COMM_IO | PCI_COMM_MAE);
1560 
1561 	/* set up kernel statistics */
1562 	if ((statep->ksp = kstat_create(IXP_NAME, ddi_get_instance(dip),
1563 	    IXP_NAME, "controller", KSTAT_TYPE_INTR, 1,
1564 	    KSTAT_FLAG_PERSISTENT)) != NULL) {
1565 		kstat_install(statep->ksp);
1566 	}
1567 
1568 
1569 	if (audioixp_chip_init(statep) != DDI_SUCCESS) {
1570 		audio_dev_warn(statep->adev, "failed to init chip");
1571 		goto error;
1572 	}
1573 
1574 	/* initialize the AC'97 part */
1575 	if (ac97_init(statep->ac97, adev) != DDI_SUCCESS) {
1576 		audio_dev_warn(adev, "ac'97 initialization failed");
1577 		goto error;
1578 	}
1579 
1580 	/* set up the interrupt handler */
1581 	if (ddi_add_intr(dip, 0, &statep->iblock, NULL, audioixp_intr,
1582 	    (caddr_t)statep) != DDI_SUCCESS) {
1583 		audio_dev_warn(adev, "bad interrupt specification");
1584 	}
1585 	statep->intr_added = B_TRUE;
1586 
1587 	if (audio_dev_register(adev) != DDI_SUCCESS) {
1588 		audio_dev_warn(adev, "unable to register with framework");
1589 		goto error;
1590 	}
1591 
1592 	ddi_report_dev(dip);
1593 
1594 	return (DDI_SUCCESS);
1595 
1596 error:
1597 	audioixp_destroy(statep);
1598 	return (DDI_FAILURE);
1599 }
1600 
1601 /*
1602  * audioixp_detach()
1603  *
1604  * Description:
1605  *	Detach an instance of the audioixp driver.
1606  *
1607  * Arguments:
1608  *	dev_info_t	*dip	Pointer to the device's dev_info struct
1609  *
1610  * Returns:
1611  *	DDI_SUCCESS	The driver was detached
1612  *	DDI_FAILURE	The driver couldn't be detached
1613  */
1614 static int
1615 audioixp_detach(dev_info_t *dip)
1616 {
1617 	audioixp_state_t	*statep;
1618 
1619 	statep = ddi_get_driver_private(dip);
1620 
1621 	if (audio_dev_unregister(statep->adev) != DDI_SUCCESS) {
1622 		return (DDI_FAILURE);
1623 	}
1624 
1625 	audioixp_destroy(statep);
1626 	return (DDI_SUCCESS);
1627 }
1628 
1629 /*
1630  * audioixp_destroy()
1631  *
1632  * Description:
1633  *	This routine releases all resources held by the device instance,
1634  *	as part of either detach or a failure in attach.
1635  *
1636  * Arguments:
1637  *	audioixp_state_t	*state	The device soft state.
1638  */
1639 void
1640 audioixp_destroy(audioixp_state_t *statep)
1641 {
1642 	if (!statep->suspended) {
1643 		PUT32(IXP_AUDIO_INT, GET32(IXP_AUDIO_INT));
1644 		PUT32(IXP_AUDIO_INT_EN, 0);
1645 
1646 		/*
1647 		 * put the audio controller into quiet state, everything off
1648 		 */
1649 		CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA);
1650 		CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA);
1651 	}
1652 
1653 	if (statep->intr_added) {
1654 		ddi_remove_intr(statep->dip, 0, statep->iblock);
1655 	}
1656 	if (statep->ksp) {
1657 		kstat_delete(statep->ksp);
1658 	}
1659 
1660 	audioixp_free_port(statep->play_port);
1661 	audioixp_free_port(statep->rec_port);
1662 
1663 	audioixp_unmap_regs(statep);
1664 
1665 	if (statep->ac97) {
1666 		ac97_free(statep->ac97);
1667 	}
1668 
1669 	if (statep->adev) {
1670 		audio_dev_free(statep->adev);
1671 	}
1672 
1673 	mutex_destroy(&statep->inst_lock);
1674 	kmem_free(statep, sizeof (*statep));
1675 }
1676