atiixp.c revision 172568
1/*-
2 * Copyright (c) 2005 Ariff Abdullah <ariff@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHERIN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * FreeBSD pcm driver for ATI IXP 150/200/250/300 AC97 controllers
29 *
30 * Features
31 *	* 16bit playback / recording
32 *	* 32bit native playback - yay!
33 *	* 32bit native recording (seems broken on few hardwares)
34 *
35 * Issues / TODO:
36 *	* SPDIF
37 *	* Support for more than 2 channels.
38 *	* VRA ? VRM ? DRA ?
39 *	* 32bit native recording seems broken on few hardwares, most
40 *	  probably because of incomplete VRA/DRA cleanup.
41 *
42 *
43 * Thanks goes to:
44 *
45 *   Shaharil @ SCAN Associates whom relentlessly providing me the
46 *   mind blowing Acer Ferrari 4002 WLMi with this ATI IXP hardware.
47 *
48 *   Reinoud Zandijk <reinoud@NetBSD.org> (auixp), which this driver is
49 *   largely based upon although large part of it has been reworked. His
50 *   driver is the primary reference and pretty much well documented.
51 *
52 *   Takashi Iwai (ALSA snd-atiixp), for register definitions and some
53 *   random ninja hackery.
54 */
55
56#include <dev/sound/pcm/sound.h>
57#include <dev/sound/pcm/ac97.h>
58
59#include <dev/pci/pcireg.h>
60#include <dev/pci/pcivar.h>
61#include <sys/sysctl.h>
62#include <sys/endian.h>
63
64#include <dev/sound/pci/atiixp.h>
65
66SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/atiixp.c 172568 2007-10-12 06:03:46Z kevlo $");
67
68#define ATI_IXP_DMA_RETRY_MAX	100
69
70#define ATI_IXP_BUFSZ_MIN	4096
71#define ATI_IXP_BUFSZ_MAX	65536
72#define ATI_IXP_BUFSZ_DEFAULT	16384
73
74#define ATI_IXP_BLK_MIN		32
75#define ATI_IXP_BLK_ALIGN	(~(ATI_IXP_BLK_MIN - 1))
76
77#define ATI_IXP_CHN_RUNNING	0x00000001
78#define ATI_IXP_CHN_SUSPEND	0x00000002
79
80struct atiixp_dma_op {
81	volatile uint32_t addr;
82	volatile uint16_t status;
83	volatile uint16_t size;
84	volatile uint32_t next;
85};
86
87struct atiixp_info;
88
89struct atiixp_chinfo {
90	struct snd_dbuf *buffer;
91	struct pcm_channel *channel;
92	struct atiixp_info *parent;
93	struct atiixp_dma_op *sgd_table;
94	bus_addr_t sgd_addr;
95	uint32_t enable_bit, flush_bit, linkptr_bit, dt_cur_bit;
96	uint32_t blksz, blkcnt;
97	uint32_t ptr, prevptr;
98	uint32_t fmt;
99	uint32_t flags;
100	int caps_32bit, dir;
101};
102
103struct atiixp_info {
104	device_t dev;
105
106	bus_space_tag_t st;
107	bus_space_handle_t sh;
108	bus_dma_tag_t parent_dmat;
109	bus_dma_tag_t sgd_dmat;
110	bus_dmamap_t sgd_dmamap;
111	bus_addr_t sgd_addr;
112
113	struct resource *reg, *irq;
114	int regtype, regid, irqid;
115	void *ih;
116	struct ac97_info *codec;
117
118	struct atiixp_chinfo pch;
119	struct atiixp_chinfo rch;
120	struct atiixp_dma_op *sgd_table;
121	struct intr_config_hook delayed_attach;
122
123	uint32_t bufsz;
124	uint32_t codec_not_ready_bits, codec_idx, codec_found;
125	uint32_t blkcnt;
126	int registered_channels;
127
128	struct mtx *lock;
129	struct callout poll_timer;
130	int poll_ticks, polling;
131};
132
133#define atiixp_rd(_sc, _reg)	\
134		bus_space_read_4((_sc)->st, (_sc)->sh, _reg)
135#define atiixp_wr(_sc, _reg, _val)	\
136		bus_space_write_4((_sc)->st, (_sc)->sh, _reg, _val)
137
138#define atiixp_lock(_sc)	snd_mtxlock((_sc)->lock)
139#define atiixp_unlock(_sc)	snd_mtxunlock((_sc)->lock)
140#define atiixp_assert(_sc)	snd_mtxassert((_sc)->lock)
141
142static uint32_t atiixp_fmt_32bit[] = {
143	AFMT_STEREO | AFMT_S16_LE,
144	AFMT_STEREO | AFMT_S32_LE,
145	0
146};
147
148static uint32_t atiixp_fmt[] = {
149	AFMT_STEREO | AFMT_S16_LE,
150	0
151};
152
153static struct pcmchan_caps atiixp_caps_32bit = {
154	ATI_IXP_BASE_RATE,
155	ATI_IXP_BASE_RATE,
156	atiixp_fmt_32bit, 0
157};
158
159static struct pcmchan_caps atiixp_caps = {
160	ATI_IXP_BASE_RATE,
161	ATI_IXP_BASE_RATE,
162	atiixp_fmt, 0
163};
164
165static const struct {
166	uint16_t vendor;
167	uint16_t devid;
168	char	 *desc;
169} atiixp_hw[] = {
170	{ ATI_VENDOR_ID, ATI_IXP_200_ID, "ATI IXP 200" },
171	{ ATI_VENDOR_ID, ATI_IXP_300_ID, "ATI IXP 300" },
172	{ ATI_VENDOR_ID, ATI_IXP_400_ID, "ATI IXP 400" },
173};
174
175static void atiixp_enable_interrupts(struct atiixp_info *);
176static void atiixp_disable_interrupts(struct atiixp_info *);
177static void atiixp_reset_aclink(struct atiixp_info *);
178static void atiixp_flush_dma(struct atiixp_chinfo *);
179static void atiixp_enable_dma(struct atiixp_chinfo *);
180static void atiixp_disable_dma(struct atiixp_chinfo *);
181
182static int atiixp_waitready_codec(struct atiixp_info *);
183static int atiixp_rdcd(kobj_t, void *, int);
184static int atiixp_wrcd(kobj_t, void *, int, uint32_t);
185
186static void  *atiixp_chan_init(kobj_t, void *, struct snd_dbuf *,
187						struct pcm_channel *, int);
188static int    atiixp_chan_setformat(kobj_t, void *, uint32_t);
189static int    atiixp_chan_setspeed(kobj_t, void *, uint32_t);
190static int    atiixp_chan_setfragments(kobj_t, void *, uint32_t, uint32_t);
191static int    atiixp_chan_setblocksize(kobj_t, void *, uint32_t);
192static void   atiixp_buildsgdt(struct atiixp_chinfo *);
193static int    atiixp_chan_trigger(kobj_t, void *, int);
194static __inline uint32_t atiixp_dmapos(struct atiixp_chinfo *);
195static int    atiixp_chan_getptr(kobj_t, void *);
196static struct pcmchan_caps *atiixp_chan_getcaps(kobj_t, void *);
197
198static void atiixp_intr(void *);
199static void atiixp_dma_cb(void *, bus_dma_segment_t *, int, int);
200static void atiixp_chip_pre_init(struct atiixp_info *);
201static void atiixp_chip_post_init(void *);
202static void atiixp_release_resource(struct atiixp_info *);
203static int  atiixp_pci_probe(device_t);
204static int  atiixp_pci_attach(device_t);
205static int  atiixp_pci_detach(device_t);
206static int  atiixp_pci_suspend(device_t);
207static int  atiixp_pci_resume(device_t);
208
209/*
210 * ATI IXP helper functions
211 */
212static void
213atiixp_enable_interrupts(struct atiixp_info *sc)
214{
215	uint32_t value;
216
217	/* clear all pending */
218	atiixp_wr(sc, ATI_REG_ISR, 0xffffffff);
219
220	/* enable all relevant interrupt sources we can handle */
221	value = atiixp_rd(sc, ATI_REG_IER);
222
223	value |= ATI_REG_IER_IO_STATUS_EN;
224
225	/*
226	 * Disable / ignore internal xrun/spdf interrupt flags
227	 * since it doesn't interest us (for now).
228	 */
229#if 1
230	value &= ~(ATI_REG_IER_IN_XRUN_EN | ATI_REG_IER_OUT_XRUN_EN |
231	    ATI_REG_IER_SPDF_XRUN_EN | ATI_REG_IER_SPDF_STATUS_EN);
232#else
233	value |= ATI_REG_IER_IN_XRUN_EN;
234	value |= ATI_REG_IER_OUT_XRUN_EN;
235
236	value |= ATI_REG_IER_SPDF_XRUN_EN;
237	value |= ATI_REG_IER_SPDF_STATUS_EN;
238#endif
239
240	atiixp_wr(sc, ATI_REG_IER, value);
241}
242
243static void
244atiixp_disable_interrupts(struct atiixp_info *sc)
245{
246	/* disable all interrupt sources */
247	atiixp_wr(sc, ATI_REG_IER, 0);
248
249	/* clear all pending */
250	atiixp_wr(sc, ATI_REG_ISR, 0xffffffff);
251}
252
253static void
254atiixp_reset_aclink(struct atiixp_info *sc)
255{
256	uint32_t value, timeout;
257
258	/* if power is down, power it up */
259	value = atiixp_rd(sc, ATI_REG_CMD);
260	if (value & ATI_REG_CMD_POWERDOWN) {
261		/* explicitly enable power */
262		value &= ~ATI_REG_CMD_POWERDOWN;
263		atiixp_wr(sc, ATI_REG_CMD, value);
264
265		/* have to wait at least 10 usec for it to initialise */
266		DELAY(20);
267	}
268
269	/* perform a soft reset */
270	value  = atiixp_rd(sc, ATI_REG_CMD);
271	value |= ATI_REG_CMD_AC_SOFT_RESET;
272	atiixp_wr(sc, ATI_REG_CMD, value);
273
274	/* need to read the CMD reg and wait aprox. 10 usec to init */
275	value  = atiixp_rd(sc, ATI_REG_CMD);
276	DELAY(20);
277
278	/* clear soft reset flag again */
279	value  = atiixp_rd(sc, ATI_REG_CMD);
280	value &= ~ATI_REG_CMD_AC_SOFT_RESET;
281	atiixp_wr(sc, ATI_REG_CMD, value);
282
283	/* check if the ac-link is working; reset device otherwise */
284	timeout = 10;
285	value = atiixp_rd(sc, ATI_REG_CMD);
286	while (!(value & ATI_REG_CMD_ACLINK_ACTIVE) && --timeout) {
287#if 0
288		device_printf(sc->dev, "not up; resetting aclink hardware\n");
289#endif
290
291		/* dip aclink reset but keep the acsync */
292		value &= ~ATI_REG_CMD_AC_RESET;
293		value |=  ATI_REG_CMD_AC_SYNC;
294		atiixp_wr(sc, ATI_REG_CMD, value);
295
296		/* need to read CMD again and wait again (clocking in issue?) */
297		value = atiixp_rd(sc, ATI_REG_CMD);
298		DELAY(20);
299
300		/* assert aclink reset again */
301		value = atiixp_rd(sc, ATI_REG_CMD);
302		value |=  ATI_REG_CMD_AC_RESET;
303		atiixp_wr(sc, ATI_REG_CMD, value);
304
305		/* check if its active now */
306		value = atiixp_rd(sc, ATI_REG_CMD);
307	}
308
309	if (timeout == 0)
310		device_printf(sc->dev, "giving up aclink reset\n");
311#if 0
312	if (timeout != 10)
313		device_printf(sc->dev, "aclink hardware reset successful\n");
314#endif
315
316	/* assert reset and sync for safety */
317	value  = atiixp_rd(sc, ATI_REG_CMD);
318	value |= ATI_REG_CMD_AC_SYNC | ATI_REG_CMD_AC_RESET;
319	atiixp_wr(sc, ATI_REG_CMD, value);
320}
321
322static void
323atiixp_flush_dma(struct atiixp_chinfo *ch)
324{
325	atiixp_wr(ch->parent, ATI_REG_FIFO_FLUSH, ch->flush_bit);
326}
327
328static void
329atiixp_enable_dma(struct atiixp_chinfo *ch)
330{
331	uint32_t value;
332
333	value = atiixp_rd(ch->parent, ATI_REG_CMD);
334	if (!(value & ch->enable_bit)) {
335		value |= ch->enable_bit;
336		atiixp_wr(ch->parent, ATI_REG_CMD, value);
337	}
338}
339
340static void
341atiixp_disable_dma(struct atiixp_chinfo *ch)
342{
343	uint32_t value;
344
345	value = atiixp_rd(ch->parent, ATI_REG_CMD);
346	if (value & ch->enable_bit) {
347		value &= ~ch->enable_bit;
348		atiixp_wr(ch->parent, ATI_REG_CMD, value);
349	}
350}
351
352/*
353 * AC97 interface
354 */
355static int
356atiixp_waitready_codec(struct atiixp_info *sc)
357{
358	int timeout = 500;
359
360	do {
361		if ((atiixp_rd(sc, ATI_REG_PHYS_OUT_ADDR) &
362		    ATI_REG_PHYS_OUT_ADDR_EN) == 0)
363			return (0);
364		DELAY(1);
365	} while (--timeout);
366
367	return (-1);
368}
369
370static int
371atiixp_rdcd(kobj_t obj, void *devinfo, int reg)
372{
373	struct atiixp_info *sc = devinfo;
374	uint32_t data;
375	int timeout;
376
377	if (atiixp_waitready_codec(sc))
378		return (-1);
379
380	data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
381	    ATI_REG_PHYS_OUT_ADDR_EN | ATI_REG_PHYS_OUT_RW | sc->codec_idx;
382
383	atiixp_wr(sc, ATI_REG_PHYS_OUT_ADDR, data);
384
385	if (atiixp_waitready_codec(sc))
386		return (-1);
387
388	timeout = 500;
389	do {
390		data = atiixp_rd(sc, ATI_REG_PHYS_IN_ADDR);
391		if (data & ATI_REG_PHYS_IN_READ_FLAG)
392			return (data >> ATI_REG_PHYS_IN_DATA_SHIFT);
393		DELAY(1);
394	} while (--timeout);
395
396	if (reg < 0x7c)
397		device_printf(sc->dev, "codec read timeout! (reg 0x%x)\n", reg);
398
399	return (-1);
400}
401
402static int
403atiixp_wrcd(kobj_t obj, void *devinfo, int reg, uint32_t data)
404{
405	struct atiixp_info *sc = devinfo;
406
407	if (atiixp_waitready_codec(sc))
408		return (-1);
409
410	data = (data << ATI_REG_PHYS_OUT_DATA_SHIFT) |
411	    (((uint32_t)reg) << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
412	    ATI_REG_PHYS_OUT_ADDR_EN | sc->codec_idx;
413
414	atiixp_wr(sc, ATI_REG_PHYS_OUT_ADDR, data);
415
416	return (0);
417}
418
419static kobj_method_t atiixp_ac97_methods[] = {
420	KOBJMETHOD(ac97_read,		atiixp_rdcd),
421	KOBJMETHOD(ac97_write,		atiixp_wrcd),
422	{ 0, 0 }
423};
424AC97_DECLARE(atiixp_ac97);
425
426/*
427 * Playback / Record channel interface
428 */
429static void *
430atiixp_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
431					struct pcm_channel *c, int dir)
432{
433	struct atiixp_info *sc = devinfo;
434	struct atiixp_chinfo *ch;
435	int num;
436
437	atiixp_lock(sc);
438
439	if (dir == PCMDIR_PLAY) {
440		ch = &sc->pch;
441		ch->linkptr_bit = ATI_REG_OUT_DMA_LINKPTR;
442		ch->enable_bit = ATI_REG_CMD_OUT_DMA_EN | ATI_REG_CMD_SEND_EN;
443		ch->flush_bit = ATI_REG_FIFO_OUT_FLUSH;
444		ch->dt_cur_bit = ATI_REG_OUT_DMA_DT_CUR;
445		/* Native 32bit playback working properly */
446		ch->caps_32bit = 1;
447	} else {
448		ch = &sc->rch;
449		ch->linkptr_bit = ATI_REG_IN_DMA_LINKPTR;
450		ch->enable_bit = ATI_REG_CMD_IN_DMA_EN | ATI_REG_CMD_RECEIVE_EN;
451		ch->flush_bit = ATI_REG_FIFO_IN_FLUSH;
452		ch->dt_cur_bit = ATI_REG_IN_DMA_DT_CUR;
453		/* XXX Native 32bit recording appear to be broken */
454		ch->caps_32bit = 1;
455	}
456
457	ch->buffer = b;
458	ch->parent = sc;
459	ch->channel = c;
460	ch->dir = dir;
461	ch->blkcnt = sc->blkcnt;
462	ch->blksz = sc->bufsz / ch->blkcnt;
463
464	atiixp_unlock(sc);
465
466	if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) == -1)
467		return (NULL);
468
469	atiixp_lock(sc);
470	num = sc->registered_channels++;
471	ch->sgd_table = &sc->sgd_table[num * ATI_IXP_DMA_CHSEGS_MAX];
472	ch->sgd_addr = sc->sgd_addr + (num * ATI_IXP_DMA_CHSEGS_MAX *
473	    sizeof(struct atiixp_dma_op));
474	atiixp_disable_dma(ch);
475	atiixp_unlock(sc);
476
477	return (ch);
478}
479
480static int
481atiixp_chan_setformat(kobj_t obj, void *data, uint32_t format)
482{
483	struct atiixp_chinfo *ch = data;
484	struct atiixp_info *sc = ch->parent;
485	uint32_t value;
486
487	atiixp_lock(sc);
488	if (ch->dir == PCMDIR_REC) {
489		value = atiixp_rd(sc, ATI_REG_CMD);
490		value &= ~ATI_REG_CMD_INTERLEAVE_IN;
491		if ((format & AFMT_32BIT) == 0)
492			value |= ATI_REG_CMD_INTERLEAVE_IN;
493		atiixp_wr(sc, ATI_REG_CMD, value);
494	} else {
495		value = atiixp_rd(sc, ATI_REG_OUT_DMA_SLOT);
496		value &= ~ATI_REG_OUT_DMA_SLOT_MASK;
497		/* We do not have support for more than 2 channels, _yet_. */
498		value |= ATI_REG_OUT_DMA_SLOT_BIT(3) |
499		    ATI_REG_OUT_DMA_SLOT_BIT(4);
500		value |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT;
501		atiixp_wr(sc, ATI_REG_OUT_DMA_SLOT, value);
502		value = atiixp_rd(sc, ATI_REG_CMD);
503		value &= ~ATI_REG_CMD_INTERLEAVE_OUT;
504		if ((format & AFMT_32BIT) == 0)
505			value |= ATI_REG_CMD_INTERLEAVE_OUT;
506		atiixp_wr(sc, ATI_REG_CMD, value);
507		value = atiixp_rd(sc, ATI_REG_6CH_REORDER);
508		value &= ~ATI_REG_6CH_REORDER_EN;
509		atiixp_wr(sc, ATI_REG_6CH_REORDER, value);
510	}
511	ch->fmt = format;
512	atiixp_unlock(sc);
513
514	return (0);
515}
516
517static int
518atiixp_chan_setspeed(kobj_t obj, void *data, uint32_t spd)
519{
520	/* XXX We're supposed to do VRA/DRA processing right here */
521	return (ATI_IXP_BASE_RATE);
522}
523
524static int
525atiixp_chan_setfragments(kobj_t obj, void *data,
526					uint32_t blksz, uint32_t blkcnt)
527{
528	struct atiixp_chinfo *ch = data;
529	struct atiixp_info *sc = ch->parent;
530
531	blksz &= ATI_IXP_BLK_ALIGN;
532
533	if (blksz > (sndbuf_getmaxsize(ch->buffer) / ATI_IXP_DMA_CHSEGS_MIN))
534		blksz = sndbuf_getmaxsize(ch->buffer) / ATI_IXP_DMA_CHSEGS_MIN;
535	if (blksz < ATI_IXP_BLK_MIN)
536		blksz = ATI_IXP_BLK_MIN;
537	if (blkcnt > ATI_IXP_DMA_CHSEGS_MAX)
538		blkcnt = ATI_IXP_DMA_CHSEGS_MAX;
539	if (blkcnt < ATI_IXP_DMA_CHSEGS_MIN)
540		blkcnt = ATI_IXP_DMA_CHSEGS_MIN;
541
542	while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) {
543		if ((blkcnt >> 1) >= ATI_IXP_DMA_CHSEGS_MIN)
544			blkcnt >>= 1;
545		else if ((blksz >> 1) >= ATI_IXP_BLK_MIN)
546			blksz >>= 1;
547		else
548			break;
549	}
550
551	if ((sndbuf_getblksz(ch->buffer) != blksz ||
552	    sndbuf_getblkcnt(ch->buffer) != blkcnt) &&
553	    sndbuf_resize(ch->buffer, blkcnt, blksz) != 0)
554		device_printf(sc->dev, "%s: failed blksz=%u blkcnt=%u\n",
555		    __func__, blksz, blkcnt);
556
557	ch->blksz = sndbuf_getblksz(ch->buffer);
558	ch->blkcnt = sndbuf_getblkcnt(ch->buffer);
559
560	return (1);
561}
562
563static int
564atiixp_chan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
565{
566	struct atiixp_chinfo *ch = data;
567	struct atiixp_info *sc = ch->parent;
568
569	atiixp_chan_setfragments(obj, data, blksz, sc->blkcnt);
570
571	return (ch->blksz);
572}
573
574static void
575atiixp_buildsgdt(struct atiixp_chinfo *ch)
576{
577	struct atiixp_info *sc = ch->parent;
578	uint32_t addr, blksz, blkcnt;
579	int i;
580
581	addr = sndbuf_getbufaddr(ch->buffer);
582
583	if (sc->polling != 0) {
584		blksz = ch->blksz * ch->blkcnt;
585		blkcnt = 1;
586	} else {
587		blksz = ch->blksz;
588		blkcnt = ch->blkcnt;
589	}
590
591	for (i = 0; i < blkcnt; i++) {
592		ch->sgd_table[i].addr = htole32(addr + (i * blksz));
593		ch->sgd_table[i].status = htole16(0);
594		ch->sgd_table[i].size = htole16(blksz >> 2);
595		ch->sgd_table[i].next = htole32((uint32_t)ch->sgd_addr +
596		    (((i + 1) % blkcnt) * sizeof(struct atiixp_dma_op)));
597	}
598}
599
600static __inline uint32_t
601atiixp_dmapos(struct atiixp_chinfo *ch)
602{
603	struct atiixp_info *sc = ch->parent;
604	uint32_t reg, addr, sz, retry;
605	volatile uint32_t ptr;
606
607	reg = ch->dt_cur_bit;
608	addr = sndbuf_getbufaddr(ch->buffer);
609	sz = ch->blkcnt * ch->blksz;
610	retry = ATI_IXP_DMA_RETRY_MAX;
611
612	do {
613		ptr = atiixp_rd(sc, reg);
614		if (ptr < addr)
615			continue;
616		ptr -= addr;
617		if (ptr < sz) {
618#if 0
619#ifdef ATI_IXP_DEBUG
620			if ((ptr & ~(ch->blksz - 1)) != ch->ptr) {
621				uint32_t delta;
622
623				delta = (sz + ptr - ch->prevptr) % sz;
624#ifndef ATI_IXP_DEBUG_VERBOSE
625				if (delta < ch->blksz)
626#endif
627					device_printf(sc->dev,
628						"PCMDIR_%s: incoherent DMA "
629						"prevptr=%u ptr=%u "
630						"ptr=%u blkcnt=%u "
631						"[delta=%u != blksz=%u] "
632						"(%s)\n",
633						(ch->dir == PCMDIR_PLAY) ?
634						"PLAY" : "REC",
635						ch->prevptr, ptr,
636						ch->ptr, ch->blkcnt,
637						delta, ch->blksz,
638						(delta < ch->blksz) ?
639						"OVERLAPPED!" : "Ok");
640				ch->ptr = ptr & ~(ch->blksz - 1);
641			}
642			ch->prevptr = ptr;
643#endif
644#endif
645			return (ptr);
646		}
647	} while (--retry);
648
649	device_printf(sc->dev, "PCMDIR_%s: invalid DMA pointer ptr=%u\n",
650	    (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC", ptr);
651
652	return (0);
653}
654
655static __inline int
656atiixp_poll_channel(struct atiixp_chinfo *ch)
657{
658	uint32_t sz, delta;
659	volatile uint32_t ptr;
660
661	if (!(ch->flags & ATI_IXP_CHN_RUNNING))
662		return (0);
663
664	sz = ch->blksz * ch->blkcnt;
665	ptr = atiixp_dmapos(ch);
666	ch->ptr = ptr;
667	ptr %= sz;
668	ptr &= ~(ch->blksz - 1);
669	delta = (sz + ptr - ch->prevptr) % sz;
670
671	if (delta < ch->blksz)
672		return (0);
673
674	ch->prevptr = ptr;
675
676	return (1);
677}
678
679#define atiixp_chan_active(sc)	(((sc)->pch.flags | (sc)->rch.flags) &	\
680				 ATI_IXP_CHN_RUNNING)
681
682static void
683atiixp_poll_callback(void *arg)
684{
685	struct atiixp_info *sc = arg;
686	uint32_t trigger = 0;
687
688	if (sc == NULL)
689		return;
690
691	atiixp_lock(sc);
692	if (sc->polling == 0 || atiixp_chan_active(sc) == 0) {
693		atiixp_unlock(sc);
694		return;
695	}
696
697	trigger |= (atiixp_poll_channel(&sc->pch) != 0) ? 1 : 0;
698	trigger |= (atiixp_poll_channel(&sc->rch) != 0) ? 2 : 0;
699
700	/* XXX */
701	callout_reset(&sc->poll_timer, 1/*sc->poll_ticks*/,
702	    atiixp_poll_callback, sc);
703
704	atiixp_unlock(sc);
705
706	if (trigger & 1)
707		chn_intr(sc->pch.channel);
708	if (trigger & 2)
709		chn_intr(sc->rch.channel);
710}
711
712static int
713atiixp_chan_trigger(kobj_t obj, void *data, int go)
714{
715	struct atiixp_chinfo *ch = data;
716	struct atiixp_info *sc = ch->parent;
717	uint32_t value;
718	int pollticks;
719
720	if (!PCMTRIG_COMMON(go))
721		return (0);
722
723	atiixp_lock(sc);
724
725	switch (go) {
726	case PCMTRIG_START:
727		atiixp_flush_dma(ch);
728		atiixp_buildsgdt(ch);
729		atiixp_wr(sc, ch->linkptr_bit, 0);
730		atiixp_enable_dma(ch);
731		atiixp_wr(sc, ch->linkptr_bit,
732		    (uint32_t)ch->sgd_addr | ATI_REG_LINKPTR_EN);
733		if (sc->polling != 0) {
734			ch->ptr = 0;
735			ch->prevptr = 0;
736			pollticks = ((uint64_t)hz * ch->blksz) /
737			    ((uint64_t)sndbuf_getbps(ch->buffer) *
738			    sndbuf_getspd(ch->buffer));
739			pollticks >>= 2;
740			if (pollticks > hz)
741				pollticks = hz;
742			if (pollticks < 1)
743				pollticks = 1;
744			if (atiixp_chan_active(sc) == 0 ||
745			    pollticks < sc->poll_ticks) {
746			    	if (bootverbose) {
747					if (atiixp_chan_active(sc) == 0)
748						device_printf(sc->dev,
749						    "%s: pollticks=%d\n",
750						    __func__, pollticks);
751					else
752						device_printf(sc->dev,
753						    "%s: pollticks %d -> %d\n",
754						    __func__, sc->poll_ticks,
755						    pollticks);
756				}
757				sc->poll_ticks = pollticks;
758				callout_reset(&sc->poll_timer, 1,
759				    atiixp_poll_callback, sc);
760			}
761		}
762		ch->flags |= ATI_IXP_CHN_RUNNING;
763		break;
764	case PCMTRIG_STOP:
765	case PCMTRIG_ABORT:
766		atiixp_disable_dma(ch);
767		atiixp_flush_dma(ch);
768		ch->flags &= ~ATI_IXP_CHN_RUNNING;
769		if (sc->polling != 0) {
770			if (atiixp_chan_active(sc) == 0) {
771				callout_stop(&sc->poll_timer);
772				sc->poll_ticks = 1;
773			} else {
774				if (sc->pch.flags & ATI_IXP_CHN_RUNNING)
775					ch = &sc->pch;
776				else
777					ch = &sc->rch;
778				pollticks = ((uint64_t)hz * ch->blksz) /
779				    ((uint64_t)sndbuf_getbps(ch->buffer) *
780				    sndbuf_getspd(ch->buffer));
781				pollticks >>= 2;
782				if (pollticks > hz)
783					pollticks = hz;
784				if (pollticks < 1)
785					pollticks = 1;
786				if (pollticks > sc->poll_ticks) {
787					if (bootverbose)
788						device_printf(sc->dev,
789						    "%s: pollticks %d -> %d\n",
790						    __func__, sc->poll_ticks,
791						    pollticks);
792					sc->poll_ticks = pollticks;
793					callout_reset(&sc->poll_timer,
794					    1, atiixp_poll_callback,
795					    sc);
796				}
797			}
798		}
799		break;
800	default:
801		atiixp_unlock(sc);
802		return (0);
803		break;
804	}
805
806	/* Update bus busy status */
807	value = atiixp_rd(sc, ATI_REG_IER);
808	if (atiixp_rd(sc, ATI_REG_CMD) & (ATI_REG_CMD_SEND_EN |
809	    ATI_REG_CMD_RECEIVE_EN | ATI_REG_CMD_SPDF_OUT_EN))
810		value |= ATI_REG_IER_SET_BUS_BUSY;
811	else
812		value &= ~ATI_REG_IER_SET_BUS_BUSY;
813	atiixp_wr(sc, ATI_REG_IER, value);
814
815	atiixp_unlock(sc);
816
817	return (0);
818}
819
820static int
821atiixp_chan_getptr(kobj_t obj, void *data)
822{
823	struct atiixp_chinfo *ch = data;
824	struct atiixp_info *sc = ch->parent;
825	uint32_t ptr;
826
827	atiixp_lock(sc);
828	if (sc->polling != 0)
829		ptr = ch->ptr;
830	else
831		ptr = atiixp_dmapos(ch);
832	atiixp_unlock(sc);
833
834	return (ptr);
835}
836
837static struct pcmchan_caps *
838atiixp_chan_getcaps(kobj_t obj, void *data)
839{
840	struct atiixp_chinfo *ch = data;
841
842	if (ch->caps_32bit)
843		return (&atiixp_caps_32bit);
844	return (&atiixp_caps);
845}
846
847static kobj_method_t atiixp_chan_methods[] = {
848	KOBJMETHOD(channel_init,		atiixp_chan_init),
849	KOBJMETHOD(channel_setformat,		atiixp_chan_setformat),
850	KOBJMETHOD(channel_setspeed,		atiixp_chan_setspeed),
851	KOBJMETHOD(channel_setblocksize,	atiixp_chan_setblocksize),
852	KOBJMETHOD(channel_setfragments,	atiixp_chan_setfragments),
853	KOBJMETHOD(channel_trigger,		atiixp_chan_trigger),
854	KOBJMETHOD(channel_getptr,		atiixp_chan_getptr),
855	KOBJMETHOD(channel_getcaps,		atiixp_chan_getcaps),
856	{ 0, 0 }
857};
858CHANNEL_DECLARE(atiixp_chan);
859
860/*
861 * PCI driver interface
862 */
863static void
864atiixp_intr(void *p)
865{
866	struct atiixp_info *sc = p;
867	uint32_t status, enable, detected_codecs;
868	uint32_t trigger = 0;
869
870	atiixp_lock(sc);
871	if (sc->polling != 0) {
872		atiixp_unlock(sc);
873		return;
874	}
875	status = atiixp_rd(sc, ATI_REG_ISR);
876
877	if (status == 0) {
878		atiixp_unlock(sc);
879		return;
880	}
881
882	if ((status & ATI_REG_ISR_OUT_STATUS) &&
883	    (sc->pch.flags & ATI_IXP_CHN_RUNNING))
884		trigger |= 1;
885	if ((status & ATI_REG_ISR_IN_STATUS) &&
886	    (sc->rch.flags & ATI_IXP_CHN_RUNNING))
887		trigger |= 2;
888
889#if 0
890	if (status & ATI_REG_ISR_IN_XRUN) {
891		device_printf(sc->dev,
892			"Recieve IN XRUN interrupt\n");
893	}
894	if (status & ATI_REG_ISR_OUT_XRUN) {
895		device_printf(sc->dev,
896			"Recieve OUT XRUN interrupt\n");
897	}
898#endif
899
900	if (status & CODEC_CHECK_BITS) {
901		/* mark missing codecs as not ready */
902		detected_codecs = status & CODEC_CHECK_BITS;
903		sc->codec_not_ready_bits |= detected_codecs;
904
905		/* disable detected interrupt sources */
906		enable  = atiixp_rd(sc, ATI_REG_IER);
907		enable &= ~detected_codecs;
908		atiixp_wr(sc, ATI_REG_IER, enable);
909		wakeup(sc);
910	}
911
912	/* acknowledge */
913	atiixp_wr(sc, ATI_REG_ISR, status);
914	atiixp_unlock(sc);
915
916	if (trigger & 1)
917		chn_intr(sc->pch.channel);
918	if (trigger & 2)
919		chn_intr(sc->rch.channel);
920}
921
922static void
923atiixp_dma_cb(void *p, bus_dma_segment_t *bds, int a, int b)
924{
925	struct atiixp_info *sc = (struct atiixp_info *)p;
926	sc->sgd_addr = bds->ds_addr;
927}
928
929static void
930atiixp_chip_pre_init(struct atiixp_info *sc)
931{
932	uint32_t value;
933
934	atiixp_lock(sc);
935
936	/* disable interrupts */
937	atiixp_disable_interrupts(sc);
938
939	/* clear all DMA enables (preserving rest of settings) */
940	value = atiixp_rd(sc, ATI_REG_CMD);
941	value &= ~(ATI_REG_CMD_IN_DMA_EN | ATI_REG_CMD_OUT_DMA_EN |
942	    ATI_REG_CMD_SPDF_OUT_EN );
943	atiixp_wr(sc, ATI_REG_CMD, value);
944
945	/* reset aclink */
946	atiixp_reset_aclink(sc);
947
948	sc->codec_not_ready_bits = 0;
949
950	/* enable all codecs to interrupt as well as the new frame interrupt */
951	atiixp_wr(sc, ATI_REG_IER, CODEC_CHECK_BITS);
952
953	atiixp_unlock(sc);
954}
955
956#ifdef SND_DYNSYSCTL
957static int
958sysctl_atiixp_polling(SYSCTL_HANDLER_ARGS)
959{
960	struct atiixp_info *sc;
961	device_t dev;
962	int err, val;
963
964	dev = oidp->oid_arg1;
965	sc = pcm_getdevinfo(dev);
966	if (sc == NULL)
967		return (EINVAL);
968	atiixp_lock(sc);
969	val = sc->polling;
970	atiixp_unlock(sc);
971	err = sysctl_handle_int(oidp, &val, 0, req);
972
973	if (err || req->newptr == NULL)
974		return (err);
975	if (val < 0 || val > 1)
976		return (EINVAL);
977
978	atiixp_lock(sc);
979	if (val != sc->polling) {
980		if (atiixp_chan_active(sc) != 0)
981			err = EBUSY;
982		else if (val == 0) {
983			atiixp_enable_interrupts(sc);
984			sc->polling = 0;
985			DELAY(1000);
986		} else {
987			atiixp_disable_interrupts(sc);
988			sc->polling = 1;
989			DELAY(1000);
990		}
991	}
992	atiixp_unlock(sc);
993
994	return (err);
995}
996#endif
997
998static void
999atiixp_chip_post_init(void *arg)
1000{
1001	struct atiixp_info *sc = (struct atiixp_info *)arg;
1002	uint32_t subdev;
1003	int i, timeout, found, polling;
1004	char status[SND_STATUSLEN];
1005
1006	atiixp_lock(sc);
1007
1008	if (sc->delayed_attach.ich_func) {
1009		config_intrhook_disestablish(&sc->delayed_attach);
1010		sc->delayed_attach.ich_func = NULL;
1011	}
1012
1013	polling = sc->polling;
1014	sc->polling = 0;
1015
1016	timeout = 10;
1017	if (sc->codec_not_ready_bits == 0) {
1018		/* wait for the interrupts to happen */
1019		do {
1020			msleep(sc, sc->lock, PWAIT, "ixpslp", max(hz / 10, 1));
1021			if (sc->codec_not_ready_bits != 0)
1022				break;
1023		} while (--timeout);
1024	}
1025
1026	sc->polling = polling;
1027	atiixp_disable_interrupts(sc);
1028
1029	if (sc->codec_not_ready_bits == 0 && timeout == 0) {
1030		device_printf(sc->dev,
1031			"WARNING: timeout during codec detection; "
1032			"codecs might be present but haven't interrupted\n");
1033		atiixp_unlock(sc);
1034		goto postinitbad;
1035	}
1036
1037	found = 0;
1038
1039	/*
1040	 * ATI IXP can have upto 3 codecs, but single codec should be
1041	 * suffice for now.
1042	 */
1043	if (!(sc->codec_not_ready_bits & ATI_REG_ISR_CODEC0_NOT_READY)) {
1044		/* codec 0 present */
1045		sc->codec_found++;
1046		sc->codec_idx = 0;
1047		found++;
1048	}
1049
1050	if (!(sc->codec_not_ready_bits & ATI_REG_ISR_CODEC1_NOT_READY)) {
1051		/* codec 1 present */
1052		sc->codec_found++;
1053	}
1054
1055	if (!(sc->codec_not_ready_bits & ATI_REG_ISR_CODEC2_NOT_READY)) {
1056		/* codec 2 present */
1057		sc->codec_found++;
1058	}
1059
1060	atiixp_unlock(sc);
1061
1062	if (found == 0)
1063		goto postinitbad;
1064
1065	/* create/init mixer */
1066	sc->codec = AC97_CREATE(sc->dev, sc, atiixp_ac97);
1067	if (sc->codec == NULL)
1068		goto postinitbad;
1069
1070	subdev = (pci_get_subdevice(sc->dev) << 16) |
1071	    pci_get_subvendor(sc->dev);
1072	switch (subdev) {
1073	case 0x11831043:	/* ASUS A6R */
1074	case 0x2043161f:	/* Maxselect x710s - http://maxselect.ru/ */
1075		ac97_setflags(sc->codec, ac97_getflags(sc->codec) |
1076		    AC97_F_EAPD_INV);
1077		break;
1078	default:
1079		break;
1080	}
1081
1082	mixer_init(sc->dev, ac97_getmixerclass(), sc->codec);
1083
1084	if (pcm_register(sc->dev, sc, ATI_IXP_NPCHAN, ATI_IXP_NRCHAN))
1085		goto postinitbad;
1086
1087	for (i = 0; i < ATI_IXP_NPCHAN; i++)
1088		pcm_addchan(sc->dev, PCMDIR_PLAY, &atiixp_chan_class, sc);
1089	for (i = 0; i < ATI_IXP_NRCHAN; i++)
1090		pcm_addchan(sc->dev, PCMDIR_REC, &atiixp_chan_class, sc);
1091
1092#ifdef SND_DYNSYSCTL
1093	SYSCTL_ADD_PROC(device_get_sysctl_ctx(sc->dev),
1094	    SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev)), OID_AUTO,
1095	    "polling", CTLTYPE_INT | CTLFLAG_RW, sc->dev, sizeof(sc->dev),
1096	    sysctl_atiixp_polling, "I", "Enable polling mode");
1097#endif
1098
1099	snprintf(status, SND_STATUSLEN, "at memory 0x%lx irq %ld %s",
1100	    rman_get_start(sc->reg), rman_get_start(sc->irq),
1101	    PCM_KLDSTRING(snd_atiixp));
1102
1103	pcm_setstatus(sc->dev, status);
1104
1105	atiixp_lock(sc);
1106	if (sc->polling == 0)
1107		atiixp_enable_interrupts(sc);
1108	atiixp_unlock(sc);
1109
1110	return;
1111
1112postinitbad:
1113	atiixp_release_resource(sc);
1114}
1115
1116static void
1117atiixp_release_resource(struct atiixp_info *sc)
1118{
1119	if (sc == NULL)
1120		return;
1121	if (sc->registered_channels != 0) {
1122		atiixp_lock(sc);
1123		sc->polling = 0;
1124		callout_stop(&sc->poll_timer);
1125		atiixp_unlock(sc);
1126		callout_drain(&sc->poll_timer);
1127	}
1128	if (sc->codec) {
1129		ac97_destroy(sc->codec);
1130		sc->codec = NULL;
1131	}
1132	if (sc->ih) {
1133		bus_teardown_intr(sc->dev, sc->irq, sc->ih);
1134		sc->ih = NULL;
1135	}
1136	if (sc->reg) {
1137		bus_release_resource(sc->dev, sc->regtype, sc->regid, sc->reg);
1138		sc->reg = NULL;
1139	}
1140	if (sc->irq) {
1141		bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irqid, sc->irq);
1142		sc->irq = NULL;
1143	}
1144	if (sc->parent_dmat) {
1145		bus_dma_tag_destroy(sc->parent_dmat);
1146		sc->parent_dmat = NULL;
1147	}
1148	if (sc->sgd_dmamap)
1149		bus_dmamap_unload(sc->sgd_dmat, sc->sgd_dmamap);
1150	if (sc->sgd_table) {
1151		bus_dmamem_free(sc->sgd_dmat, sc->sgd_table, sc->sgd_dmamap);
1152		sc->sgd_table = NULL;
1153	}
1154	sc->sgd_dmamap = NULL;
1155	if (sc->sgd_dmat) {
1156		bus_dma_tag_destroy(sc->sgd_dmat);
1157		sc->sgd_dmat = NULL;
1158	}
1159	if (sc->lock) {
1160		snd_mtxfree(sc->lock);
1161		sc->lock = NULL;
1162	}
1163	free(sc, M_DEVBUF);
1164}
1165
1166static int
1167atiixp_pci_probe(device_t dev)
1168{
1169	int i;
1170	uint16_t devid, vendor;
1171
1172	vendor = pci_get_vendor(dev);
1173	devid = pci_get_device(dev);
1174	for (i = 0; i < sizeof(atiixp_hw) / sizeof(atiixp_hw[0]); i++) {
1175		if (vendor == atiixp_hw[i].vendor &&
1176		    devid == atiixp_hw[i].devid) {
1177			device_set_desc(dev, atiixp_hw[i].desc);
1178			return (BUS_PROBE_DEFAULT);
1179		}
1180	}
1181
1182	return (ENXIO);
1183}
1184
1185static int
1186atiixp_pci_attach(device_t dev)
1187{
1188	struct atiixp_info *sc;
1189	int i;
1190
1191	sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
1192	sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_atiixp softc");
1193	sc->dev = dev;
1194
1195	callout_init(&sc->poll_timer, CALLOUT_MPSAFE);
1196	sc->poll_ticks = 1;
1197
1198	if (resource_int_value(device_get_name(sc->dev),
1199	    device_get_unit(sc->dev), "polling", &i) == 0 && i != 0)
1200		sc->polling = 1;
1201	else
1202		sc->polling = 0;
1203
1204	pci_set_powerstate(dev, PCI_POWERSTATE_D0);
1205	pci_enable_busmaster(dev);
1206
1207	sc->regid = PCIR_BAR(0);
1208	sc->regtype = SYS_RES_MEMORY;
1209	sc->reg = bus_alloc_resource_any(dev, sc->regtype,
1210	    &sc->regid, RF_ACTIVE);
1211
1212	if (!sc->reg) {
1213		device_printf(dev, "unable to allocate register space\n");
1214		goto bad;
1215	}
1216
1217	sc->st = rman_get_bustag(sc->reg);
1218	sc->sh = rman_get_bushandle(sc->reg);
1219
1220	sc->bufsz = pcm_getbuffersize(dev, ATI_IXP_BUFSZ_MIN,
1221	    ATI_IXP_BUFSZ_DEFAULT, ATI_IXP_BUFSZ_MAX);
1222
1223	sc->irqid = 0;
1224	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
1225	    RF_ACTIVE | RF_SHAREABLE);
1226	if (!sc->irq || snd_setup_intr(dev, sc->irq, INTR_MPSAFE,
1227	    atiixp_intr, sc, &sc->ih)) {
1228		device_printf(dev, "unable to map interrupt\n");
1229		goto bad;
1230	}
1231
1232	/*
1233	 * Let the user choose the best DMA segments.
1234	 */
1235	if (resource_int_value(device_get_name(dev),
1236	    device_get_unit(dev), "blocksize", &i) == 0 && i > 0) {
1237		i &= ATI_IXP_BLK_ALIGN;
1238		if (i < ATI_IXP_BLK_MIN)
1239			i = ATI_IXP_BLK_MIN;
1240		sc->blkcnt = sc->bufsz / i;
1241		i = 0;
1242		while (sc->blkcnt >> i)
1243			i++;
1244		sc->blkcnt = 1 << (i - 1);
1245		if (sc->blkcnt < ATI_IXP_DMA_CHSEGS_MIN)
1246			sc->blkcnt = ATI_IXP_DMA_CHSEGS_MIN;
1247		else if (sc->blkcnt > ATI_IXP_DMA_CHSEGS_MAX)
1248			sc->blkcnt = ATI_IXP_DMA_CHSEGS_MAX;
1249
1250	} else
1251		sc->blkcnt = ATI_IXP_DMA_CHSEGS;
1252
1253	/*
1254	 * DMA tag for scatter-gather buffers and link pointers
1255	 */
1256	if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
1257		/*boundary*/0,
1258		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
1259		/*highaddr*/BUS_SPACE_MAXADDR,
1260		/*filter*/NULL, /*filterarg*/NULL,
1261		/*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
1262		/*flags*/0, /*lockfunc*/NULL,
1263		/*lockarg*/NULL, &sc->parent_dmat) != 0) {
1264		device_printf(dev, "unable to create dma tag\n");
1265		goto bad;
1266	}
1267
1268	if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
1269		/*boundary*/0,
1270		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
1271		/*highaddr*/BUS_SPACE_MAXADDR,
1272		/*filter*/NULL, /*filterarg*/NULL,
1273		/*maxsize*/ATI_IXP_DMA_CHSEGS_MAX * ATI_IXP_NCHANS *
1274		sizeof(struct atiixp_dma_op),
1275		/*nsegments*/1, /*maxsegz*/0x3ffff,
1276		/*flags*/0, /*lockfunc*/NULL,
1277		/*lockarg*/NULL, &sc->sgd_dmat) != 0) {
1278		device_printf(dev, "unable to create dma tag\n");
1279		goto bad;
1280	}
1281
1282	if (bus_dmamem_alloc(sc->sgd_dmat, (void **)&sc->sgd_table,
1283	    BUS_DMA_NOWAIT, &sc->sgd_dmamap) == -1)
1284		goto bad;
1285
1286	if (bus_dmamap_load(sc->sgd_dmat, sc->sgd_dmamap, sc->sgd_table,
1287	    ATI_IXP_DMA_CHSEGS_MAX * ATI_IXP_NCHANS *
1288	    sizeof(struct atiixp_dma_op), atiixp_dma_cb, sc, 0))
1289		goto bad;
1290
1291
1292	atiixp_chip_pre_init(sc);
1293
1294	sc->delayed_attach.ich_func = atiixp_chip_post_init;
1295	sc->delayed_attach.ich_arg = sc;
1296	if (cold == 0 ||
1297	    config_intrhook_establish(&sc->delayed_attach) != 0) {
1298		sc->delayed_attach.ich_func = NULL;
1299		atiixp_chip_post_init(sc);
1300	}
1301
1302	return (0);
1303
1304bad:
1305	atiixp_release_resource(sc);
1306	return (ENXIO);
1307}
1308
1309static int
1310atiixp_pci_detach(device_t dev)
1311{
1312	int r;
1313	struct atiixp_info *sc;
1314
1315	sc = pcm_getdevinfo(dev);
1316	if (sc != NULL) {
1317		if (sc->codec != NULL) {
1318			r = pcm_unregister(dev);
1319			if (r)
1320				return (r);
1321		}
1322		sc->codec = NULL;
1323		if (sc->st != 0 && sc->sh != 0)
1324			atiixp_disable_interrupts(sc);
1325		atiixp_release_resource(sc);
1326	}
1327	return (0);
1328}
1329
1330static int
1331atiixp_pci_suspend(device_t dev)
1332{
1333	struct atiixp_info *sc = pcm_getdevinfo(dev);
1334	uint32_t value;
1335
1336	/* quickly disable interrupts and save channels active state */
1337	atiixp_lock(sc);
1338	atiixp_disable_interrupts(sc);
1339	atiixp_unlock(sc);
1340
1341	/* stop everything */
1342	if (sc->pch.flags & ATI_IXP_CHN_RUNNING) {
1343		atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_STOP);
1344		sc->pch.flags |= ATI_IXP_CHN_SUSPEND;
1345	}
1346	if (sc->rch.flags & ATI_IXP_CHN_RUNNING) {
1347		atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_STOP);
1348		sc->rch.flags |= ATI_IXP_CHN_SUSPEND;
1349	}
1350
1351	/* power down aclink and pci bus */
1352	atiixp_lock(sc);
1353	value = atiixp_rd(sc, ATI_REG_CMD);
1354	value |= ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET;
1355	atiixp_wr(sc, ATI_REG_CMD, ATI_REG_CMD_POWERDOWN);
1356	pci_set_powerstate(dev, PCI_POWERSTATE_D3);
1357	atiixp_unlock(sc);
1358
1359	return (0);
1360}
1361
1362static int
1363atiixp_pci_resume(device_t dev)
1364{
1365	struct atiixp_info *sc = pcm_getdevinfo(dev);
1366
1367	atiixp_lock(sc);
1368	/* power up pci bus */
1369	pci_set_powerstate(dev, PCI_POWERSTATE_D0);
1370	pci_enable_io(dev, SYS_RES_MEMORY);
1371	pci_enable_busmaster(dev);
1372	/* reset / power up aclink */
1373	atiixp_reset_aclink(sc);
1374	atiixp_unlock(sc);
1375
1376	if (mixer_reinit(dev) == -1) {
1377		device_printf(dev, "unable to reinitialize the mixer\n");
1378		return (ENXIO);
1379	}
1380
1381	/*
1382	 * Resume channel activities. Reset channel format regardless
1383	 * of its previous state.
1384	 */
1385	if (sc->pch.channel != NULL) {
1386		if (sc->pch.fmt != 0)
1387			atiixp_chan_setformat(NULL, &sc->pch, sc->pch.fmt);
1388		if (sc->pch.flags & ATI_IXP_CHN_SUSPEND) {
1389			sc->pch.flags &= ~ATI_IXP_CHN_SUSPEND;
1390			atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_START);
1391		}
1392	}
1393	if (sc->rch.channel != NULL) {
1394		if (sc->rch.fmt != 0)
1395			atiixp_chan_setformat(NULL, &sc->rch, sc->rch.fmt);
1396		if (sc->rch.flags & ATI_IXP_CHN_SUSPEND) {
1397			sc->rch.flags &= ~ATI_IXP_CHN_SUSPEND;
1398			atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_START);
1399		}
1400	}
1401
1402	/* enable interrupts */
1403	atiixp_lock(sc);
1404	if (sc->polling == 0)
1405		atiixp_enable_interrupts(sc);
1406	atiixp_unlock(sc);
1407
1408	return (0);
1409}
1410
1411static device_method_t atiixp_methods[] = {
1412	DEVMETHOD(device_probe,		atiixp_pci_probe),
1413	DEVMETHOD(device_attach,	atiixp_pci_attach),
1414	DEVMETHOD(device_detach,	atiixp_pci_detach),
1415	DEVMETHOD(device_suspend,	atiixp_pci_suspend),
1416	DEVMETHOD(device_resume,	atiixp_pci_resume),
1417	{ 0, 0 }
1418};
1419
1420static driver_t atiixp_driver = {
1421	"pcm",
1422	atiixp_methods,
1423	PCM_SOFTC_SIZE,
1424};
1425
1426DRIVER_MODULE(snd_atiixp, pci, atiixp_driver, pcm_devclass, 0, 0);
1427MODULE_DEPEND(snd_atiixp, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
1428MODULE_VERSION(snd_atiixp, 1);
1429