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