xref: /dragonfly/sys/dev/sound/pci/atiixp.c (revision 3f5e28f4)
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  * $FreeBSD: src/sys/dev/sound/pci/atiixp.c,v 1.2.2.5 2006/11/14 13:08:11 ariff Exp $
27  * $DragonFly: src/sys/dev/sound/pci/atiixp.c,v 1.3 2007/05/13 18:33:58 swildner Exp $
28  */
29 
30 /*
31  * FreeBSD pcm driver for ATI IXP 150/200/250/300 AC97 controllers
32  *
33  * Features
34  *	* 16bit playback / recording
35  *	* 32bit native playback - yay!
36  *	* 32bit native recording (seems broken on few hardwares)
37  *
38  * Issues / TODO:
39  *	* SPDIF
40  *	* Support for more than 2 channels.
41  *	* VRA ? VRM ? DRA ?
42  *	* 32bit native recording seems broken on few hardwares, most
43  *	  probably because of incomplete VRA/DRA cleanup.
44  *
45  *
46  * Thanks goes to:
47  *
48  *   Shaharil @ SCAN Associates whom relentlessly providing me the
49  *   mind blowing Acer Ferrari 4002 WLMi with this ATI IXP hardware.
50  *
51  *   Reinoud Zandijk <reinoud@NetBSD.org> (auixp), which this driver is
52  *   largely based upon although large part of it has been reworked. His
53  *   driver is the primary reference and pretty much well documented.
54  *
55  *   Takashi Iwai (ALSA snd-atiixp), for register definitions and some
56  *   random ninja hackery.
57  */
58 
59 #include <dev/sound/pcm/sound.h>
60 #include <dev/sound/pcm/ac97.h>
61 
62 #include <bus/pci/pcireg.h>
63 #include <bus/pci/pcivar.h>
64 #include <sys/sysctl.h>
65 #include <sys/endian.h>
66 
67 #include <dev/sound/pci/atiixp.h>
68 
69 SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/atiixp.c,v 1.3 2007/05/13 18:33:58 swildner Exp $");
70 
71 struct atiixp_dma_op {
72 	volatile uint32_t addr;
73 	volatile uint16_t status;
74 	volatile uint16_t size;
75 	volatile uint32_t next;
76 };
77 
78 struct atiixp_info;
79 
80 struct atiixp_chinfo {
81 	struct snd_dbuf *buffer;
82 	struct pcm_channel *channel;
83 	struct atiixp_info *parent;
84 	struct atiixp_dma_op *sgd_table;
85 	bus_addr_t sgd_addr;
86 	uint32_t enable_bit, flush_bit, linkptr_bit, dma_dt_cur_bit;
87 	uint32_t dma_segs;
88 	uint32_t fmt;
89 	int caps_32bit, dir, active;
90 };
91 
92 struct atiixp_info {
93 	device_t dev;
94 
95 	bus_space_tag_t st;
96 	bus_space_handle_t sh;
97 	bus_dma_tag_t parent_dmat;
98 	bus_dma_tag_t sgd_dmat;
99 	bus_dmamap_t sgd_dmamap;
100 	bus_addr_t sgd_addr;
101 
102 	struct resource *reg, *irq;
103 	int regtype, regid, irqid;
104 	void *ih;
105 	struct ac97_info *codec;
106 
107 	struct atiixp_chinfo pch;
108 	struct atiixp_chinfo rch;
109 	struct atiixp_dma_op *sgd_table;
110 	struct intr_config_hook delayed_attach;
111 
112 	uint32_t bufsz;
113 	uint32_t codec_not_ready_bits, codec_idx, codec_found;
114 	uint32_t dma_segs;
115 	int registered_channels;
116 
117 	struct spinlock *lock;
118 };
119 
120 #define atiixp_rd(_sc, _reg)	\
121 		bus_space_read_4((_sc)->st, (_sc)->sh, _reg)
122 #define atiixp_wr(_sc, _reg, _val)	\
123 		bus_space_write_4((_sc)->st, (_sc)->sh, _reg, _val)
124 
125 #define atiixp_lock(_sc)	snd_mtxlock((_sc)->lock)
126 #define atiixp_unlock(_sc)	snd_mtxunlock((_sc)->lock)
127 #define atiixp_assert(_sc)	snd_mtxassert((_sc)->lock)
128 
129 static uint32_t atiixp_fmt_32bit[] = {
130 	AFMT_STEREO | AFMT_S16_LE,
131 	AFMT_STEREO | AFMT_S32_LE,
132 	0
133 };
134 
135 static uint32_t atiixp_fmt[] = {
136 	AFMT_STEREO | AFMT_S16_LE,
137 	0
138 };
139 
140 static struct pcmchan_caps atiixp_caps_32bit = {
141 	ATI_IXP_BASE_RATE,
142 	ATI_IXP_BASE_RATE,
143 	atiixp_fmt_32bit, 0
144 };
145 
146 static struct pcmchan_caps atiixp_caps = {
147 	ATI_IXP_BASE_RATE,
148 	ATI_IXP_BASE_RATE,
149 	atiixp_fmt, 0
150 };
151 
152 static const struct {
153 	uint16_t vendor;
154 	uint16_t devid;
155 	char	 *desc;
156 } atiixp_hw[] = {
157 	{ ATI_VENDOR_ID, ATI_IXP_200_ID, "ATI IXP 200" },
158 	{ ATI_VENDOR_ID, ATI_IXP_300_ID, "ATI IXP 300" },
159 	{ ATI_VENDOR_ID, ATI_IXP_400_ID, "ATI IXP 400" },
160 };
161 
162 static void atiixp_enable_interrupts(struct atiixp_info *);
163 static void atiixp_disable_interrupts(struct atiixp_info *);
164 static void atiixp_reset_aclink(struct atiixp_info *);
165 static void atiixp_flush_dma(struct atiixp_info *, struct atiixp_chinfo *);
166 static void atiixp_enable_dma(struct atiixp_info *, struct atiixp_chinfo *);
167 static void atiixp_disable_dma(struct atiixp_info *, struct atiixp_chinfo *);
168 
169 static int atiixp_waitready_codec(struct atiixp_info *);
170 static int atiixp_rdcd(kobj_t, void *, int);
171 static int atiixp_wrcd(kobj_t, void *, int, uint32_t);
172 
173 static void  *atiixp_chan_init(kobj_t, void *, struct snd_dbuf *,
174 						struct pcm_channel *, int);
175 static int    atiixp_chan_setformat(kobj_t, void *, uint32_t);
176 static int    atiixp_chan_setspeed(kobj_t, void *, uint32_t);
177 static int    atiixp_chan_setblocksize(kobj_t, void *, uint32_t);
178 static void   atiixp_buildsgdt(struct atiixp_chinfo *);
179 static int    atiixp_chan_trigger(kobj_t, void *, int);
180 static int    atiixp_chan_getptr(kobj_t, void *);
181 static struct pcmchan_caps *atiixp_chan_getcaps(kobj_t, void *);
182 
183 static void atiixp_intr(void *);
184 static void atiixp_dma_cb(void *, bus_dma_segment_t *, int, int);
185 static void atiixp_chip_pre_init(struct atiixp_info *);
186 static void atiixp_chip_post_init(void *);
187 static void atiixp_release_resource(struct atiixp_info *);
188 static int  atiixp_pci_probe(device_t);
189 static int  atiixp_pci_attach(device_t);
190 static int  atiixp_pci_detach(device_t);
191 static int  atiixp_pci_suspend(device_t);
192 static int  atiixp_pci_resume(device_t);
193 
194 /*
195  * ATI IXP helper functions
196  */
197 static void
198 atiixp_enable_interrupts(struct atiixp_info *sc)
199 {
200 	uint32_t value;
201 
202 	/* clear all pending */
203 	atiixp_wr(sc, ATI_REG_ISR, 0xffffffff);
204 
205 	/* enable all relevant interrupt sources we can handle */
206 	value = atiixp_rd(sc, ATI_REG_IER);
207 
208 	value |= ATI_REG_IER_IO_STATUS_EN;
209 
210 	/*
211 	 * Disable / ignore internal xrun/spdf interrupt flags
212 	 * since it doesn't interest us (for now).
213 	 */
214 #if 0
215 	value |= ATI_REG_IER_IN_XRUN_EN;
216 	value |= ATI_REG_IER_OUT_XRUN_EN;
217 
218 	value |= ATI_REG_IER_SPDF_XRUN_EN;
219 	value |= ATI_REG_IER_SPDF_STATUS_EN;
220 #endif
221 
222 	atiixp_wr(sc, ATI_REG_IER, value);
223 }
224 
225 static void
226 atiixp_disable_interrupts(struct atiixp_info *sc)
227 {
228 	/* disable all interrupt sources */
229 	atiixp_wr(sc, ATI_REG_IER, 0);
230 
231 	/* clear all pending */
232 	atiixp_wr(sc, ATI_REG_ISR, 0xffffffff);
233 }
234 
235 static void
236 atiixp_reset_aclink(struct atiixp_info *sc)
237 {
238 	uint32_t value, timeout;
239 
240 	/* if power is down, power it up */
241 	value = atiixp_rd(sc, ATI_REG_CMD);
242 	if (value & ATI_REG_CMD_POWERDOWN) {
243 		/* explicitly enable power */
244 		value &= ~ATI_REG_CMD_POWERDOWN;
245 		atiixp_wr(sc, ATI_REG_CMD, value);
246 
247 		/* have to wait at least 10 usec for it to initialise */
248 		DELAY(20);
249 	};
250 
251 	/* perform a soft reset */
252 	value  = atiixp_rd(sc, ATI_REG_CMD);
253 	value |= ATI_REG_CMD_AC_SOFT_RESET;
254 	atiixp_wr(sc, ATI_REG_CMD, value);
255 
256 	/* need to read the CMD reg and wait aprox. 10 usec to init */
257 	value  = atiixp_rd(sc, ATI_REG_CMD);
258 	DELAY(20);
259 
260 	/* clear soft reset flag again */
261 	value  = atiixp_rd(sc, ATI_REG_CMD);
262 	value &= ~ATI_REG_CMD_AC_SOFT_RESET;
263 	atiixp_wr(sc, ATI_REG_CMD, value);
264 
265 	/* check if the ac-link is working; reset device otherwise */
266 	timeout = 10;
267 	value = atiixp_rd(sc, ATI_REG_CMD);
268 	while (!(value & ATI_REG_CMD_ACLINK_ACTIVE)
269 						&& --timeout) {
270 #if 0
271 		device_printf(sc->dev, "not up; resetting aclink hardware\n");
272 #endif
273 
274 		/* dip aclink reset but keep the acsync */
275 		value &= ~ATI_REG_CMD_AC_RESET;
276 		value |=  ATI_REG_CMD_AC_SYNC;
277 		atiixp_wr(sc, ATI_REG_CMD, value);
278 
279 		/* need to read CMD again and wait again (clocking in issue?) */
280 		value = atiixp_rd(sc, ATI_REG_CMD);
281 		DELAY(20);
282 
283 		/* assert aclink reset again */
284 		value = atiixp_rd(sc, ATI_REG_CMD);
285 		value |=  ATI_REG_CMD_AC_RESET;
286 		atiixp_wr(sc, ATI_REG_CMD, value);
287 
288 		/* check if its active now */
289 		value = atiixp_rd(sc, ATI_REG_CMD);
290 	};
291 
292 	if (timeout == 0)
293 		device_printf(sc->dev, "giving up aclink reset\n");
294 #if 0
295 	if (timeout != 10)
296 		device_printf(sc->dev, "aclink hardware reset successful\n");
297 #endif
298 
299 	/* assert reset and sync for safety */
300 	value  = atiixp_rd(sc, ATI_REG_CMD);
301 	value |= ATI_REG_CMD_AC_SYNC | ATI_REG_CMD_AC_RESET;
302 	atiixp_wr(sc, ATI_REG_CMD, value);
303 }
304 
305 static void
306 atiixp_flush_dma(struct atiixp_info *sc, struct atiixp_chinfo *ch)
307 {
308 	atiixp_wr(sc, ATI_REG_FIFO_FLUSH, ch->flush_bit);
309 }
310 
311 static void
312 atiixp_enable_dma(struct atiixp_info *sc, struct atiixp_chinfo *ch)
313 {
314 	uint32_t value;
315 
316 	value = atiixp_rd(sc, ATI_REG_CMD);
317 	if (!(value & ch->enable_bit)) {
318 		value |= ch->enable_bit;
319 		atiixp_wr(sc, ATI_REG_CMD, value);
320 	}
321 }
322 
323 static void
324 atiixp_disable_dma(struct atiixp_info *sc, struct atiixp_chinfo *ch)
325 {
326 	uint32_t value;
327 
328 	value = atiixp_rd(sc, ATI_REG_CMD);
329 	if (value & ch->enable_bit) {
330 		value &= ~ch->enable_bit;
331 		atiixp_wr(sc, ATI_REG_CMD, value);
332 	}
333 }
334 
335 /*
336  * AC97 interface
337  */
338 static int
339 atiixp_waitready_codec(struct atiixp_info *sc)
340 {
341 	int timeout = 500;
342 
343 	do {
344 		if ((atiixp_rd(sc, ATI_REG_PHYS_OUT_ADDR) &
345 				ATI_REG_PHYS_OUT_ADDR_EN) == 0)
346 			return 0;
347 		DELAY(1);
348 	} while (timeout--);
349 
350 	return -1;
351 }
352 
353 static int
354 atiixp_rdcd(kobj_t obj, void *devinfo, int reg)
355 {
356 	struct atiixp_info *sc = devinfo;
357 	uint32_t data;
358 	int timeout;
359 
360 	if (atiixp_waitready_codec(sc))
361 		return -1;
362 
363 	data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
364 			ATI_REG_PHYS_OUT_ADDR_EN |
365 			ATI_REG_PHYS_OUT_RW | sc->codec_idx;
366 
367 	atiixp_wr(sc, ATI_REG_PHYS_OUT_ADDR, data);
368 
369 	if (atiixp_waitready_codec(sc))
370 		return -1;
371 
372 	timeout = 500;
373 	do {
374 		data = atiixp_rd(sc, ATI_REG_PHYS_IN_ADDR);
375 		if (data & ATI_REG_PHYS_IN_READ_FLAG)
376 			return data >> ATI_REG_PHYS_IN_DATA_SHIFT;
377 		DELAY(1);
378 	} while (timeout--);
379 
380 	if (reg < 0x7c)
381 		device_printf(sc->dev, "codec read timeout! (reg 0x%x)\n", reg);
382 
383 	return -1;
384 }
385 
386 static int
387 atiixp_wrcd(kobj_t obj, void *devinfo, int reg, uint32_t data)
388 {
389 	struct atiixp_info *sc = devinfo;
390 
391 	if (atiixp_waitready_codec(sc))
392 		return -1;
393 
394 	data = (data << ATI_REG_PHYS_OUT_DATA_SHIFT) |
395 			(((uint32_t)reg) << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
396 			ATI_REG_PHYS_OUT_ADDR_EN | sc->codec_idx;
397 
398 	atiixp_wr(sc, ATI_REG_PHYS_OUT_ADDR, data);
399 
400 	return 0;
401 }
402 
403 static kobj_method_t atiixp_ac97_methods[] = {
404     	KOBJMETHOD(ac97_read,		atiixp_rdcd),
405     	KOBJMETHOD(ac97_write,		atiixp_wrcd),
406 	{ 0, 0 }
407 };
408 AC97_DECLARE(atiixp_ac97);
409 
410 /*
411  * Playback / Record channel interface
412  */
413 static void *
414 atiixp_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
415 					struct pcm_channel *c, int dir)
416 {
417 	struct atiixp_info *sc = devinfo;
418 	struct atiixp_chinfo *ch;
419 	int num;
420 
421 	atiixp_lock(sc);
422 
423 	if (dir == PCMDIR_PLAY) {
424 		ch = &sc->pch;
425 		ch->linkptr_bit = ATI_REG_OUT_DMA_LINKPTR;
426 		ch->enable_bit = ATI_REG_CMD_OUT_DMA_EN | ATI_REG_CMD_SEND_EN;
427 		ch->flush_bit = ATI_REG_FIFO_OUT_FLUSH;
428 		ch->dma_dt_cur_bit = ATI_REG_OUT_DMA_DT_CUR;
429 		/* Native 32bit playback working properly */
430 		ch->caps_32bit = 1;
431 	} else {
432 		ch = &sc->rch;
433 		ch->linkptr_bit = ATI_REG_IN_DMA_LINKPTR;
434 		ch->enable_bit = ATI_REG_CMD_IN_DMA_EN  | ATI_REG_CMD_RECEIVE_EN;
435 		ch->flush_bit = ATI_REG_FIFO_IN_FLUSH;
436 		ch->dma_dt_cur_bit = ATI_REG_IN_DMA_DT_CUR;
437 		/* XXX Native 32bit recording appear to be broken */
438 		ch->caps_32bit = 1;
439 	}
440 
441 	ch->buffer = b;
442 	ch->parent = sc;
443 	ch->channel = c;
444 	ch->dir = dir;
445 	ch->dma_segs = sc->dma_segs;
446 
447 	atiixp_unlock(sc);
448 
449 	if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) == -1)
450 		return NULL;
451 
452 	atiixp_lock(sc);
453 	num = sc->registered_channels++;
454 	ch->sgd_table = &sc->sgd_table[num * ch->dma_segs];
455 	ch->sgd_addr = sc->sgd_addr +
456 			(num * ch->dma_segs * sizeof(struct atiixp_dma_op));
457 	atiixp_disable_dma(sc, ch);
458 	atiixp_unlock(sc);
459 
460 	return ch;
461 }
462 
463 static int
464 atiixp_chan_setformat(kobj_t obj, void *data, uint32_t format)
465 {
466 	struct atiixp_chinfo *ch = data;
467 	struct atiixp_info *sc = ch->parent;
468 	uint32_t value;
469 
470 	atiixp_lock(sc);
471 	if (ch->dir == PCMDIR_REC) {
472 		value = atiixp_rd(sc, ATI_REG_CMD);
473 		value &= ~ATI_REG_CMD_INTERLEAVE_IN;
474 		if ((format & AFMT_32BIT) == 0)
475 			value |= ATI_REG_CMD_INTERLEAVE_IN;
476 		atiixp_wr(sc, ATI_REG_CMD, value);
477 	} else {
478 		value = atiixp_rd(sc, ATI_REG_OUT_DMA_SLOT);
479 		value &= ~ATI_REG_OUT_DMA_SLOT_MASK;
480 		/* We do not have support for more than 2 channels, _yet_. */
481 		value |= ATI_REG_OUT_DMA_SLOT_BIT(3) |
482 				ATI_REG_OUT_DMA_SLOT_BIT(4);
483 		value |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT;
484 		atiixp_wr(sc, ATI_REG_OUT_DMA_SLOT, value);
485 		value = atiixp_rd(sc, ATI_REG_CMD);
486 		value &= ~ATI_REG_CMD_INTERLEAVE_OUT;
487 		if ((format & AFMT_32BIT) == 0)
488 			value |= ATI_REG_CMD_INTERLEAVE_OUT;
489 		atiixp_wr(sc, ATI_REG_CMD, value);
490 		value = atiixp_rd(sc, ATI_REG_6CH_REORDER);
491 		value &= ~ATI_REG_6CH_REORDER_EN;
492 		atiixp_wr(sc, ATI_REG_6CH_REORDER, value);
493 	}
494 	ch->fmt = format;
495 	atiixp_unlock(sc);
496 
497 	return 0;
498 }
499 
500 static int
501 atiixp_chan_setspeed(kobj_t obj, void *data, uint32_t spd)
502 {
503 	/* XXX We're supposed to do VRA/DRA processing right here */
504 	return ATI_IXP_BASE_RATE;
505 }
506 
507 static int
508 atiixp_chan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
509 {
510 	struct atiixp_chinfo *ch = data;
511 	struct atiixp_info *sc = ch->parent;
512 
513 	if (blksz > (sc->bufsz / ch->dma_segs))
514 		blksz = sc->bufsz / ch->dma_segs;
515 
516 	sndbuf_resize(ch->buffer, ch->dma_segs, blksz);
517 
518 	return sndbuf_getblksz(ch->buffer);
519 }
520 
521 static void
522 atiixp_buildsgdt(struct atiixp_chinfo *ch)
523 {
524 	uint32_t addr, blksz;
525 	int i;
526 
527 	addr = sndbuf_getbufaddr(ch->buffer);
528 	blksz = sndbuf_getblksz(ch->buffer);
529 
530 	for (i = 0; i < ch->dma_segs; i++) {
531 		ch->sgd_table[i].addr = htole32(addr + (i * blksz));
532 		ch->sgd_table[i].status = htole16(0);
533 		ch->sgd_table[i].size = htole16(blksz >> 2);
534 		ch->sgd_table[i].next = htole32((uint32_t)ch->sgd_addr +
535 						(((i + 1) % ch->dma_segs) *
536 						sizeof(struct atiixp_dma_op)));
537 	}
538 }
539 
540 static int
541 atiixp_chan_trigger(kobj_t obj, void *data, int go)
542 {
543 	struct atiixp_chinfo *ch = data;
544 	struct atiixp_info *sc = ch->parent;
545 	uint32_t value;
546 
547 	atiixp_lock(sc);
548 
549 	switch (go) {
550 		case PCMTRIG_START:
551 			atiixp_flush_dma(sc, ch);
552 			atiixp_buildsgdt(ch);
553 			atiixp_wr(sc, ch->linkptr_bit, 0);
554 			atiixp_enable_dma(sc, ch);
555 			atiixp_wr(sc, ch->linkptr_bit,
556 				(uint32_t)ch->sgd_addr | ATI_REG_LINKPTR_EN);
557 			break;
558 		case PCMTRIG_STOP:
559 		case PCMTRIG_ABORT:
560 			atiixp_disable_dma(sc, ch);
561 			atiixp_flush_dma(sc, ch);
562 			break;
563 		default:
564 			atiixp_unlock(sc);
565 			return 0;
566 			break;
567 	}
568 
569 	/* Update bus busy status */
570 	value = atiixp_rd(sc, ATI_REG_IER);
571 	if (atiixp_rd(sc, ATI_REG_CMD) & (
572 			ATI_REG_CMD_SEND_EN | ATI_REG_CMD_RECEIVE_EN |
573 			ATI_REG_CMD_SPDF_OUT_EN))
574 		value |= ATI_REG_IER_SET_BUS_BUSY;
575 	else
576 		value &= ~ATI_REG_IER_SET_BUS_BUSY;
577 	atiixp_wr(sc, ATI_REG_IER, value);
578 
579 	atiixp_unlock(sc);
580 
581 	return 0;
582 }
583 
584 static int
585 atiixp_chan_getptr(kobj_t obj, void *data)
586 {
587 	struct atiixp_chinfo *ch = data;
588 	struct atiixp_info *sc = ch->parent;
589 	uint32_t addr, align, retry, sz;
590 	volatile uint32_t ptr;
591 
592 	addr = sndbuf_getbufaddr(ch->buffer);
593 	align = (ch->fmt & AFMT_32BIT) ? 7 : 3;
594 	retry = 100;
595 	sz = sndbuf_getblksz(ch->buffer) * ch->dma_segs;
596 
597 	atiixp_lock(sc);
598 	do {
599 		ptr = atiixp_rd(sc, ch->dma_dt_cur_bit);
600 		if (ptr < addr)
601 			continue;
602 		ptr -= addr;
603 		if (ptr < sz && !(ptr & align))
604 			break;
605 	} while (--retry);
606 	atiixp_unlock(sc);
607 
608 #if 0
609 	if (retry != 100) {
610 		device_printf(sc->dev,
611 		    "%saligned hwptr: dir=PCMDIR_%s ptr=%u fmt=0x%08x retry=%d\n",
612 		    (ptr & align) ? "un" : "",
613 		    (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC", ptr,
614 		    ch->fmt, 100 - retry);
615 	}
616 #endif
617 
618 	return (retry > 0) ? ptr : 0;
619 }
620 
621 static struct pcmchan_caps *
622 atiixp_chan_getcaps(kobj_t obj, void *data)
623 {
624 	struct atiixp_chinfo *ch = data;
625 
626 	if (ch->caps_32bit)
627 		return &atiixp_caps_32bit;
628 	return &atiixp_caps;
629 }
630 
631 static kobj_method_t atiixp_chan_methods[] = {
632 	KOBJMETHOD(channel_init,		atiixp_chan_init),
633 	KOBJMETHOD(channel_setformat,		atiixp_chan_setformat),
634 	KOBJMETHOD(channel_setspeed,		atiixp_chan_setspeed),
635 	KOBJMETHOD(channel_setblocksize,	atiixp_chan_setblocksize),
636 	KOBJMETHOD(channel_trigger,		atiixp_chan_trigger),
637 	KOBJMETHOD(channel_getptr,		atiixp_chan_getptr),
638 	KOBJMETHOD(channel_getcaps,		atiixp_chan_getcaps),
639 	{ 0, 0 }
640 };
641 CHANNEL_DECLARE(atiixp_chan);
642 
643 /*
644  * PCI driver interface
645  */
646 static void
647 atiixp_intr(void *p)
648 {
649 	struct atiixp_info *sc = p;
650 	uint32_t status, enable, detected_codecs;
651 
652 	atiixp_lock(sc);
653 	status = atiixp_rd(sc, ATI_REG_ISR);
654 
655 	if (status == 0) {
656 		atiixp_unlock(sc);
657 		return;
658 	}
659 
660 	if ((status & ATI_REG_ISR_IN_STATUS) && sc->rch.channel) {
661 		atiixp_unlock(sc);
662 		chn_intr(sc->rch.channel);
663 		atiixp_lock(sc);
664 	}
665 	if ((status & ATI_REG_ISR_OUT_STATUS) && sc->pch.channel) {
666 		atiixp_unlock(sc);
667 		chn_intr(sc->pch.channel);
668 		atiixp_lock(sc);
669 	}
670 
671 #if 0
672 	if (status & ATI_REG_ISR_IN_XRUN) {
673 		device_printf(sc->dev,
674 			"Receive IN XRUN interrupt\n");
675 	}
676 	if (status & ATI_REG_ISR_OUT_XRUN) {
677 		device_printf(sc->dev,
678 			"Receive OUT XRUN interrupt\n");
679 	}
680 #endif
681 
682 	if (status & CODEC_CHECK_BITS) {
683 		/* mark missing codecs as not ready */
684 		detected_codecs = status & CODEC_CHECK_BITS;
685 		sc->codec_not_ready_bits |= detected_codecs;
686 
687 		/* disable detected interupt sources */
688 		enable  = atiixp_rd(sc, ATI_REG_IER);
689 		enable &= ~detected_codecs;
690 		atiixp_wr(sc, ATI_REG_IER, enable);
691 	}
692 
693 	/* acknowledge */
694 	atiixp_wr(sc, ATI_REG_ISR, status);
695 	atiixp_unlock(sc);
696 }
697 
698 static void
699 atiixp_dma_cb(void *p, bus_dma_segment_t *bds, int a, int b)
700 {
701 	struct atiixp_info *sc = (struct atiixp_info *)p;
702 	sc->sgd_addr = bds->ds_addr;
703 }
704 
705 static void
706 atiixp_chip_pre_init(struct atiixp_info *sc)
707 {
708 	uint32_t value;
709 
710 	atiixp_lock(sc);
711 
712 	/* disable interrupts */
713 	atiixp_disable_interrupts(sc);
714 
715 	/* clear all DMA enables (preserving rest of settings) */
716 	value = atiixp_rd(sc, ATI_REG_CMD);
717 	value &= ~(ATI_REG_CMD_IN_DMA_EN | ATI_REG_CMD_OUT_DMA_EN |
718 						ATI_REG_CMD_SPDF_OUT_EN );
719 	atiixp_wr(sc, ATI_REG_CMD, value);
720 
721 	/* reset aclink */
722 	atiixp_reset_aclink(sc);
723 
724 	sc->codec_not_ready_bits = 0;
725 
726 	/* enable all codecs to interrupt as well as the new frame interrupt */
727 	atiixp_wr(sc, ATI_REG_IER, CODEC_CHECK_BITS);
728 
729 	atiixp_unlock(sc);
730 }
731 
732 static void
733 atiixp_chip_post_init(void *arg)
734 {
735 	struct atiixp_info *sc = (struct atiixp_info *)arg;
736 	uint32_t subdev;
737 	int i, timeout, found;
738 	char status[SND_STATUSLEN];
739 
740 	atiixp_lock(sc);
741 
742 	if (sc->delayed_attach.ich_func) {
743 		config_intrhook_disestablish(&sc->delayed_attach);
744 		sc->delayed_attach.ich_func = NULL;
745 	}
746 
747 	/* wait for the interrupts to happen */
748 	timeout = 100;
749 	while (--timeout) {
750 		msleep(sc, sc->lock, 0, "ixpslp", 1);
751 		if (sc->codec_not_ready_bits)
752 			break;
753 	}
754 
755 	atiixp_disable_interrupts(sc);
756 
757 	if (timeout == 0) {
758 		device_printf(sc->dev,
759 			"WARNING: timeout during codec detection; "
760 			"codecs might be present but haven't interrupted\n");
761 		atiixp_unlock(sc);
762 		goto postinitbad;
763 	}
764 
765 	found = 0;
766 
767 	/*
768 	 * ATI IXP can have upto 3 codecs, but single codec should be
769 	 * suffice for now.
770 	 */
771 	if (!(sc->codec_not_ready_bits &
772 				ATI_REG_ISR_CODEC0_NOT_READY)) {
773 		/* codec 0 present */
774 		sc->codec_found++;
775 		sc->codec_idx = 0;
776 		found++;
777 	}
778 
779 	if (!(sc->codec_not_ready_bits &
780 				ATI_REG_ISR_CODEC1_NOT_READY)) {
781 		/* codec 1 present */
782 		sc->codec_found++;
783 	}
784 
785 	if (!(sc->codec_not_ready_bits &
786 				ATI_REG_ISR_CODEC2_NOT_READY)) {
787 		/* codec 2 present */
788 		sc->codec_found++;
789 	}
790 
791 	atiixp_unlock(sc);
792 
793 	if (found == 0)
794 		goto postinitbad;
795 
796 	/* create/init mixer */
797 	sc->codec = AC97_CREATE(sc->dev, sc, atiixp_ac97);
798 	if (sc->codec == NULL)
799 		goto postinitbad;
800 
801 	subdev = (pci_get_subdevice(sc->dev) << 16) | pci_get_subvendor(sc->dev);
802 	switch (subdev) {
803 	case 0x2043161f:	/* Maxselect x710s - http://maxselect.ru/ */
804 		ac97_setflags(sc->codec, ac97_getflags(sc->codec) | AC97_F_EAPD_INV);
805 		break;
806 	default:
807 		break;
808 	}
809 
810 	mixer_init(sc->dev, ac97_getmixerclass(), sc->codec);
811 
812 	if (pcm_register(sc->dev, sc, ATI_IXP_NPCHAN, ATI_IXP_NRCHAN))
813 		goto postinitbad;
814 
815 	for (i = 0; i < ATI_IXP_NPCHAN; i++)
816 		pcm_addchan(sc->dev, PCMDIR_PLAY, &atiixp_chan_class, sc);
817 	for (i = 0; i < ATI_IXP_NRCHAN; i++)
818 		pcm_addchan(sc->dev, PCMDIR_REC, &atiixp_chan_class, sc);
819 
820 	ksnprintf(status, SND_STATUSLEN, "at memory 0x%lx irq %ld %s",
821 			rman_get_start(sc->reg), rman_get_start(sc->irq),
822 			PCM_KLDSTRING(snd_atiixp));
823 
824 	pcm_setstatus(sc->dev, status);
825 
826 	atiixp_lock(sc);
827 	atiixp_enable_interrupts(sc);
828 	atiixp_unlock(sc);
829 
830 	return;
831 
832 postinitbad:
833 	atiixp_release_resource(sc);
834 }
835 
836 static void
837 atiixp_release_resource(struct atiixp_info *sc)
838 {
839 	if (sc == NULL)
840 		return;
841 	if (sc->codec) {
842 		ac97_destroy(sc->codec);
843 		sc->codec = NULL;
844 	}
845 	if (sc->ih) {
846 		bus_teardown_intr(sc->dev, sc->irq, sc->ih);
847 		sc->ih = 0;
848 	}
849 	if (sc->reg) {
850 		bus_release_resource(sc->dev, sc->regtype, sc->regid, sc->reg);
851 		sc->reg = 0;
852 	}
853 	if (sc->irq) {
854 		bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irqid, sc->irq);
855 		sc->irq = 0;
856 	}
857 	if (sc->parent_dmat) {
858 		bus_dma_tag_destroy(sc->parent_dmat);
859 		sc->parent_dmat = 0;
860 	}
861 	if (sc->sgd_dmamap) {
862 		bus_dmamap_unload(sc->sgd_dmat, sc->sgd_dmamap);
863 		sc->sgd_dmamap = 0;
864 	}
865 	if (sc->sgd_dmat) {
866 		bus_dma_tag_destroy(sc->sgd_dmat);
867 		sc->sgd_dmat = 0;
868 	}
869 	if (sc->lock) {
870 		snd_mtxfree(sc->lock);
871 		sc->lock = NULL;
872 	}
873 }
874 
875 static int
876 atiixp_pci_probe(device_t dev)
877 {
878 	int i;
879 	uint16_t devid, vendor;
880 
881 	vendor = pci_get_vendor(dev);
882 	devid = pci_get_device(dev);
883 	for (i = 0; i < sizeof(atiixp_hw)/sizeof(atiixp_hw[0]); i++) {
884 		if (vendor == atiixp_hw[i].vendor &&
885 					devid == atiixp_hw[i].devid) {
886 			device_set_desc(dev, atiixp_hw[i].desc);
887 			return BUS_PROBE_DEFAULT;
888 		}
889 	}
890 
891 	return ENXIO;
892 }
893 
894 static int
895 atiixp_pci_attach(device_t dev)
896 {
897 	struct atiixp_info *sc;
898 	int i;
899 
900 	if ((sc = kmalloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
901 		device_printf(dev, "cannot allocate softc\n");
902 		return ENXIO;
903 	}
904 
905 	sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
906 	sc->dev = dev;
907 	/*
908 	 * Default DMA segments per playback / recording channel
909 	 */
910 	sc->dma_segs = ATI_IXP_DMA_CHSEGS;
911 
912 	pci_set_powerstate(dev, PCI_POWERSTATE_D0);
913 	pci_enable_busmaster(dev);
914 
915 	sc->regid = PCIR_BAR(0);
916 	sc->regtype = SYS_RES_MEMORY;
917 	sc->reg = bus_alloc_resource_any(dev, sc->regtype, &sc->regid,
918 								RF_ACTIVE);
919 
920 	if (!sc->reg) {
921 		device_printf(dev, "unable to allocate register space\n");
922 		goto bad;
923 	}
924 
925 	sc->st = rman_get_bustag(sc->reg);
926 	sc->sh = rman_get_bushandle(sc->reg);
927 
928 	sc->bufsz = pcm_getbuffersize(dev, 4096, ATI_IXP_DEFAULT_BUFSZ, 65536);
929 
930 	sc->irqid = 0;
931 	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
932 						RF_ACTIVE | RF_SHAREABLE);
933 	if (!sc->irq ||
934 			snd_setup_intr(dev, sc->irq, INTR_MPSAFE,
935 						atiixp_intr, sc, &sc->ih)) {
936 		device_printf(dev, "unable to map interrupt\n");
937 		goto bad;
938 	}
939 
940 	/*
941 	 * Let the user choose the best DMA segments.
942 	 */
943 	 if (resource_int_value(device_get_name(dev),
944 			device_get_unit(dev), "dma_segs",
945 			&i) == 0) {
946 		if (i < ATI_IXP_DMA_CHSEGS_MIN)
947 			i = ATI_IXP_DMA_CHSEGS_MIN;
948 		if (i > ATI_IXP_DMA_CHSEGS_MAX)
949 			i = ATI_IXP_DMA_CHSEGS_MAX;
950 		sc->dma_segs = i;
951 	}
952 
953 	/*
954 	 * round the value to the nearest ^2
955 	 */
956 	i = 0;
957 	while (sc->dma_segs >> i)
958 		i++;
959 	sc->dma_segs = 1 << (i - 1);
960 	if (sc->dma_segs < ATI_IXP_DMA_CHSEGS_MIN)
961 		sc->dma_segs = ATI_IXP_DMA_CHSEGS_MIN;
962 	else if (sc->dma_segs > ATI_IXP_DMA_CHSEGS_MAX)
963 		sc->dma_segs = ATI_IXP_DMA_CHSEGS_MAX;
964 
965 	/*
966 	 * DMA tag for scatter-gather buffers and link pointers
967 	 */
968 	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
969 		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
970 		/*highaddr*/BUS_SPACE_MAXADDR,
971 		/*filter*/NULL, /*filterarg*/NULL,
972 		/*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
973 		/*flags*/0,
974 		&sc->parent_dmat) != 0) {
975 		device_printf(dev, "unable to create dma tag\n");
976 		goto bad;
977 	}
978 
979 	if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
980 		/*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
981 		/*highaddr*/BUS_SPACE_MAXADDR,
982 		/*filter*/NULL, /*filterarg*/NULL,
983 		/*maxsize*/sc->dma_segs * ATI_IXP_NCHANS *
984 						sizeof(struct atiixp_dma_op),
985 		/*nsegments*/1, /*maxsegz*/0x3ffff,
986 		/*flags*/0,
987 		&sc->sgd_dmat) != 0) {
988 		device_printf(dev, "unable to create dma tag\n");
989 		goto bad;
990 	}
991 
992 	if (bus_dmamem_alloc(sc->sgd_dmat, (void **)&sc->sgd_table,
993 				BUS_DMA_NOWAIT, &sc->sgd_dmamap) == -1)
994 		goto bad;
995 
996 	if (bus_dmamap_load(sc->sgd_dmat, sc->sgd_dmamap, sc->sgd_table,
997 				sc->dma_segs * ATI_IXP_NCHANS *
998 						sizeof(struct atiixp_dma_op),
999 				atiixp_dma_cb, sc, 0))
1000 		goto bad;
1001 
1002 
1003 	atiixp_chip_pre_init(sc);
1004 
1005 	sc->delayed_attach.ich_func = atiixp_chip_post_init;
1006 	sc->delayed_attach.ich_arg = sc;
1007 	if (cold == 0 ||
1008 			config_intrhook_establish(&sc->delayed_attach) != 0) {
1009 		sc->delayed_attach.ich_func = NULL;
1010 		atiixp_chip_post_init(sc);
1011 	}
1012 
1013 	return 0;
1014 
1015 bad:
1016 	atiixp_release_resource(sc);
1017 	return ENXIO;
1018 }
1019 
1020 static int
1021 atiixp_pci_detach(device_t dev)
1022 {
1023 	int r;
1024 	struct atiixp_info *sc;
1025 
1026 	sc = pcm_getdevinfo(dev);
1027 	if (sc != NULL) {
1028 		if (sc->codec != NULL) {
1029 			r = pcm_unregister(dev);
1030 			if (r)
1031 				return r;
1032 		}
1033 		sc->codec = NULL;
1034 		atiixp_disable_interrupts(sc);
1035 		atiixp_release_resource(sc);
1036 		kfree(sc, M_DEVBUF);
1037 	}
1038 	return 0;
1039 }
1040 
1041 static int
1042 atiixp_pci_suspend(device_t dev)
1043 {
1044 	struct atiixp_info *sc = pcm_getdevinfo(dev);
1045 	uint32_t value;
1046 
1047 	/* quickly disable interrupts and save channels active state */
1048 	atiixp_lock(sc);
1049 	atiixp_disable_interrupts(sc);
1050 	value = atiixp_rd(sc, ATI_REG_CMD);
1051 	sc->pch.active = (value & ATI_REG_CMD_SEND_EN) ? 1 : 0;
1052 	sc->rch.active = (value & ATI_REG_CMD_RECEIVE_EN) ? 1 : 0;
1053 	atiixp_unlock(sc);
1054 
1055 	/* stop everything */
1056 	if (sc->pch.channel && sc->pch.active)
1057 		atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_STOP);
1058 	if (sc->rch.channel && sc->rch.active)
1059 		atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_STOP);
1060 
1061 	/* power down aclink and pci bus */
1062 	atiixp_lock(sc);
1063 	value = atiixp_rd(sc, ATI_REG_CMD);
1064 	value |= ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET;
1065 	atiixp_wr(sc, ATI_REG_CMD, ATI_REG_CMD_POWERDOWN);
1066 	pci_set_powerstate(dev, PCI_POWERSTATE_D3);
1067 	atiixp_unlock(sc);
1068 
1069 	return 0;
1070 }
1071 
1072 static int
1073 atiixp_pci_resume(device_t dev)
1074 {
1075 	struct atiixp_info *sc = pcm_getdevinfo(dev);
1076 
1077 	atiixp_lock(sc);
1078 	/* power up pci bus */
1079 	pci_set_powerstate(dev, PCI_POWERSTATE_D0);
1080 	pci_enable_io(dev, SYS_RES_MEMORY);
1081 	pci_enable_busmaster(dev);
1082 	/* reset / power up aclink */
1083 	atiixp_reset_aclink(sc);
1084 	atiixp_unlock(sc);
1085 
1086 	if (mixer_reinit(dev) == -1) {
1087 		device_printf(dev, "unable to reinitialize the mixer\n");
1088 		return ENXIO;
1089 	}
1090 
1091 	/*
1092 	 * Resume channel activities. Reset channel format regardless
1093 	 * of its previous state.
1094 	 */
1095 	if (sc->pch.channel) {
1096 		if (sc->pch.fmt)
1097 			atiixp_chan_setformat(NULL, &sc->pch, sc->pch.fmt);
1098 		if (sc->pch.active)
1099 			atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_START);
1100 	}
1101 	if (sc->rch.channel) {
1102 		if (sc->rch.fmt)
1103 			atiixp_chan_setformat(NULL, &sc->rch, sc->rch.fmt);
1104 		if (sc->rch.active)
1105 			atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_START);
1106 	}
1107 
1108 	/* enable interrupts */
1109 	atiixp_lock(sc);
1110 	atiixp_enable_interrupts(sc);
1111 	atiixp_unlock(sc);
1112 
1113 	return 0;
1114 }
1115 
1116 static device_method_t atiixp_methods[] = {
1117 	DEVMETHOD(device_probe,		atiixp_pci_probe),
1118 	DEVMETHOD(device_attach,	atiixp_pci_attach),
1119 	DEVMETHOD(device_detach,	atiixp_pci_detach),
1120 	DEVMETHOD(device_suspend,	atiixp_pci_suspend),
1121 	DEVMETHOD(device_resume,	atiixp_pci_resume),
1122 	{ 0, 0 }
1123 };
1124 
1125 static driver_t atiixp_driver = {
1126 	"pcm",
1127 	atiixp_methods,
1128 	PCM_SOFTC_SIZE,
1129 };
1130 
1131 DRIVER_MODULE(snd_atiixp, pci, atiixp_driver, pcm_devclass, 0, 0);
1132 MODULE_DEPEND(snd_atiixp, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
1133 MODULE_VERSION(snd_atiixp, 1);
1134