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