audioixp.c revision 9484:fbd5ddc28e96
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 */
25
26/*
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 */
61static int audioixp_ddi_attach(dev_info_t *, ddi_attach_cmd_t);
62static int audioixp_ddi_detach(dev_info_t *, ddi_detach_cmd_t);
63static int audioixp_quiesce(dev_info_t *);
64static int audioixp_resume(dev_info_t *);
65static int audioixp_suspend(dev_info_t *);
66
67/*
68 * Entry point routine prototypes
69 */
70static int audioixp_open(void *, int, unsigned *, unsigned *, caddr_t *);
71static void audioixp_close(void *);
72static int audioixp_start(void *);
73static void audioixp_stop(void *);
74static int audioixp_format(void *);
75static int audioixp_channels(void *);
76static int audioixp_rate(void *);
77static uint64_t audioixp_count(void *);
78static void audioixp_sync(void *, unsigned);
79static size_t audioixp_qlen(void *);
80
81static 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 */
99static uint_t	audioixp_intr(caddr_t);
100
101/*
102 * Local Routine Prototypes
103 */
104static int audioixp_attach(dev_info_t *);
105static int audioixp_detach(dev_info_t *);
106static int audioixp_alloc_port(audioixp_state_t *, int);
107static void audioixp_start_port(audioixp_port_t *);
108static void audioixp_stop_port(audioixp_port_t *);
109static void audioixp_reset_port(audioixp_port_t *);
110static void audioixp_update_port(audioixp_port_t *);
111
112static int audioixp_codec_sync(audioixp_state_t *);
113static void audioixp_wr97(void *, uint8_t, uint16_t);
114static uint16_t audioixp_rd97(void *, uint8_t);
115static int audioixp_reset_ac97(audioixp_state_t *);
116static int audioixp_map_regs(audioixp_state_t *);
117static void audioixp_unmap_regs(audioixp_state_t *);
118static int audioixp_chip_init(audioixp_state_t *);
119static 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 */
130static 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 */
146static 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 */
153static 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 */
162static struct ddi_device_acc_attr dev_attr = {
163	DDI_DEVICE_ATTR_V0,
164	DDI_STRUCTURE_LE_ACC,
165	DDI_STRICTORDER_ACC
166};
167static 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 */
176static 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 */
194static 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 */
223int
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 */
249int
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 */
275int
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 */
298static int
299audioixp_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 */
329static int
330audioixp_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
347static void
348audioixp_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
354static void
355audioixp_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 */
370static int
371audioixp_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
387static int
388audioixp_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
407static void
408audioixp_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
423static int
424audioixp_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 */
473static uint_t
474audioixp_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 */
543static int
544audioixp_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 */
576static void
577audioixp_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 */
598static void
599audioixp_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 */
624static int
625audioixp_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 */
651static int
652audioixp_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 */
671static int
672audioixp_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 */
691static int
692audioixp_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 */
711static uint64_t
712audioixp_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 */
735static void
736audioixp_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 */
756static size_t
757audioixp_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 */
781static int
782audioixp_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	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 */
951static void
952audioixp_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 */
991static void
992audioixp_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 */
1019static void
1020audioixp_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 */
1046static void
1047audioixp_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 */
1115static void
1116audioixp_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 */
1176static int
1177audioixp_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 */
1205static void
1206audioixp_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 */
1231static int
1232audioixp_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 */
1263static int
1264audioixp_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 */
1294static uint16_t
1295audioixp_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
1321done:
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 */
1337static void
1338audioixp_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 */
1370static int
1371audioixp_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 */
1423static int
1424audioixp_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 */
1469static int
1470audioixp_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
1596error:
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 */
1614static int
1615audioixp_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 */
1639void
1640audioixp_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