Add support for trimmed down version of ATI SB600 AC97 audio
[dragonfly.git] / sys / dev / sound / pci / atiixp.c
blob573cb46f9be6d952a61d260546f858c21edce8cb
1 /*-
2 * Copyright (c) 2005 Ariff Abdullah <ariff@FreeBSD.org>
3 * All rights reserved.
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.
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.
26 * $FreeBSD: src/sys/dev/sound/pci/atiixp.c,v 1.2.2.8 2007/11/06 02:08:25 ariff Exp $
27 * $DragonFly: src/sys/dev/sound/pci/atiixp.c,v 1.6 2007/11/30 08:01:43 hasso Exp $
31 * FreeBSD pcm driver for ATI IXP 150/200/250/300 AC97 controllers
33 * Features
34 * * 16bit playback / recording
35 * * 32bit native playback - yay!
36 * * 32bit native recording (seems broken on few hardwares)
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.
46 * Thanks goes to:
48 * Shaharil @ SCAN Associates whom relentlessly providing me the
49 * mind blowing Acer Ferrari 4002 WLMi with this ATI IXP hardware.
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.
55 * Takashi Iwai (ALSA snd-atiixp), for register definitions and some
56 * random ninja hackery.
59 #include <dev/sound/pcm/sound.h>
60 #include <dev/sound/pcm/ac97.h>
62 #include <bus/pci/pcireg.h>
63 #include <bus/pci/pcivar.h>
64 #include <sys/sysctl.h>
65 #include <sys/endian.h>
67 #include <dev/sound/pci/atiixp.h>
69 SND_DECLARE_FILE("$DragonFly: src/sys/dev/sound/pci/atiixp.c,v 1.6 2007/11/30 08:01:43 hasso Exp $");
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;
78 struct atiixp_info;
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;
92 struct atiixp_info {
93 device_t dev;
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;
102 struct resource *reg, *irq;
103 int regtype, regid, irqid;
104 void *ih;
105 struct ac97_info *codec;
107 struct atiixp_chinfo pch;
108 struct atiixp_chinfo rch;
109 struct atiixp_dma_op *sgd_table;
110 struct intr_config_hook delayed_attach;
112 uint32_t bufsz;
113 uint32_t codec_not_ready_bits, codec_idx, codec_found;
114 uint32_t dma_segs;
115 int registered_channels;
117 sndlock_t lock;
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)
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)
129 static uint32_t atiixp_fmt_32bit[] = {
130 AFMT_STEREO | AFMT_S16_LE,
131 AFMT_STEREO | AFMT_S32_LE,
135 static uint32_t atiixp_fmt[] = {
136 AFMT_STEREO | AFMT_S16_LE,
140 static struct pcmchan_caps atiixp_caps_32bit = {
141 ATI_IXP_BASE_RATE,
142 ATI_IXP_BASE_RATE,
143 atiixp_fmt_32bit, 0
146 static struct pcmchan_caps atiixp_caps = {
147 ATI_IXP_BASE_RATE,
148 ATI_IXP_BASE_RATE,
149 atiixp_fmt, 0
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 { ATI_VENDOR_ID, ATI_IXP_SB600_ID, "ATI IXP SB600" },
163 static void atiixp_enable_interrupts(struct atiixp_info *);
164 static void atiixp_disable_interrupts(struct atiixp_info *);
165 static void atiixp_reset_aclink(struct atiixp_info *);
166 static void atiixp_flush_dma(struct atiixp_info *, struct atiixp_chinfo *);
167 static void atiixp_enable_dma(struct atiixp_info *, struct atiixp_chinfo *);
168 static void atiixp_disable_dma(struct atiixp_info *, struct atiixp_chinfo *);
170 static int atiixp_waitready_codec(struct atiixp_info *);
171 static int atiixp_rdcd(kobj_t, void *, int);
172 static int atiixp_wrcd(kobj_t, void *, int, uint32_t);
174 static void *atiixp_chan_init(kobj_t, void *, struct snd_dbuf *,
175 struct pcm_channel *, int);
176 static int atiixp_chan_setformat(kobj_t, void *, uint32_t);
177 static int atiixp_chan_setspeed(kobj_t, void *, uint32_t);
178 static int atiixp_chan_setblocksize(kobj_t, void *, uint32_t);
179 static void atiixp_buildsgdt(struct atiixp_chinfo *);
180 static int atiixp_chan_trigger(kobj_t, void *, int);
181 static int atiixp_chan_getptr(kobj_t, void *);
182 static struct pcmchan_caps *atiixp_chan_getcaps(kobj_t, void *);
184 static void atiixp_intr(void *);
185 static void atiixp_dma_cb(void *, bus_dma_segment_t *, int, int);
186 static void atiixp_chip_pre_init(struct atiixp_info *);
187 static void atiixp_chip_post_init(void *);
188 static void atiixp_release_resource(struct atiixp_info *);
189 static int atiixp_pci_probe(device_t);
190 static int atiixp_pci_attach(device_t);
191 static int atiixp_pci_detach(device_t);
192 static int atiixp_pci_suspend(device_t);
193 static int atiixp_pci_resume(device_t);
196 * ATI IXP helper functions
198 static void
199 atiixp_enable_interrupts(struct atiixp_info *sc)
201 uint32_t value;
203 /* clear all pending */
204 atiixp_wr(sc, ATI_REG_ISR, 0xffffffff);
206 /* enable all relevant interrupt sources we can handle */
207 value = atiixp_rd(sc, ATI_REG_IER);
209 value |= ATI_REG_IER_IO_STATUS_EN;
212 * Disable / ignore internal xrun/spdf interrupt flags
213 * since it doesn't interest us (for now).
215 #if 0
216 value |= ATI_REG_IER_IN_XRUN_EN;
217 value |= ATI_REG_IER_OUT_XRUN_EN;
219 value |= ATI_REG_IER_SPDF_XRUN_EN;
220 value |= ATI_REG_IER_SPDF_STATUS_EN;
221 #endif
223 atiixp_wr(sc, ATI_REG_IER, value);
226 static void
227 atiixp_disable_interrupts(struct atiixp_info *sc)
229 /* disable all interrupt sources */
230 atiixp_wr(sc, ATI_REG_IER, 0);
232 /* clear all pending */
233 atiixp_wr(sc, ATI_REG_ISR, 0xffffffff);
236 static void
237 atiixp_reset_aclink(struct atiixp_info *sc)
239 uint32_t value, timeout;
241 /* if power is down, power it up */
242 value = atiixp_rd(sc, ATI_REG_CMD);
243 if (value & ATI_REG_CMD_POWERDOWN) {
244 /* explicitly enable power */
245 value &= ~ATI_REG_CMD_POWERDOWN;
246 atiixp_wr(sc, ATI_REG_CMD, value);
248 /* have to wait at least 10 usec for it to initialise */
249 DELAY(20);
252 /* perform a soft reset */
253 value = atiixp_rd(sc, ATI_REG_CMD);
254 value |= ATI_REG_CMD_AC_SOFT_RESET;
255 atiixp_wr(sc, ATI_REG_CMD, value);
257 /* need to read the CMD reg and wait aprox. 10 usec to init */
258 value = atiixp_rd(sc, ATI_REG_CMD);
259 DELAY(20);
261 /* clear soft reset flag again */
262 value = atiixp_rd(sc, ATI_REG_CMD);
263 value &= ~ATI_REG_CMD_AC_SOFT_RESET;
264 atiixp_wr(sc, ATI_REG_CMD, value);
266 /* check if the ac-link is working; reset device otherwise */
267 timeout = 10;
268 value = atiixp_rd(sc, ATI_REG_CMD);
269 while (!(value & ATI_REG_CMD_ACLINK_ACTIVE)
270 && --timeout) {
271 #if 0
272 device_printf(sc->dev, "not up; resetting aclink hardware\n");
273 #endif
275 /* dip aclink reset but keep the acsync */
276 value &= ~ATI_REG_CMD_AC_RESET;
277 value |= ATI_REG_CMD_AC_SYNC;
278 atiixp_wr(sc, ATI_REG_CMD, value);
280 /* need to read CMD again and wait again (clocking in issue?) */
281 value = atiixp_rd(sc, ATI_REG_CMD);
282 DELAY(20);
284 /* assert aclink reset again */
285 value = atiixp_rd(sc, ATI_REG_CMD);
286 value |= ATI_REG_CMD_AC_RESET;
287 atiixp_wr(sc, ATI_REG_CMD, value);
289 /* check if its active now */
290 value = atiixp_rd(sc, ATI_REG_CMD);
293 if (timeout == 0)
294 device_printf(sc->dev, "giving up aclink reset\n");
295 #if 0
296 if (timeout != 10)
297 device_printf(sc->dev, "aclink hardware reset successful\n");
298 #endif
300 /* assert reset and sync for safety */
301 value = atiixp_rd(sc, ATI_REG_CMD);
302 value |= ATI_REG_CMD_AC_SYNC | ATI_REG_CMD_AC_RESET;
303 atiixp_wr(sc, ATI_REG_CMD, value);
306 static void
307 atiixp_flush_dma(struct atiixp_info *sc, struct atiixp_chinfo *ch)
309 atiixp_wr(sc, ATI_REG_FIFO_FLUSH, ch->flush_bit);
312 static void
313 atiixp_enable_dma(struct atiixp_info *sc, struct atiixp_chinfo *ch)
315 uint32_t value;
317 value = atiixp_rd(sc, ATI_REG_CMD);
318 if (!(value & ch->enable_bit)) {
319 value |= ch->enable_bit;
320 atiixp_wr(sc, ATI_REG_CMD, value);
324 static void
325 atiixp_disable_dma(struct atiixp_info *sc, struct atiixp_chinfo *ch)
327 uint32_t value;
329 value = atiixp_rd(sc, ATI_REG_CMD);
330 if (value & ch->enable_bit) {
331 value &= ~ch->enable_bit;
332 atiixp_wr(sc, ATI_REG_CMD, value);
337 * AC97 interface
339 static int
340 atiixp_waitready_codec(struct atiixp_info *sc)
342 int timeout = 500;
344 do {
345 if ((atiixp_rd(sc, ATI_REG_PHYS_OUT_ADDR) &
346 ATI_REG_PHYS_OUT_ADDR_EN) == 0)
347 return 0;
348 DELAY(1);
349 } while (timeout--);
351 return -1;
354 static int
355 atiixp_rdcd(kobj_t obj, void *devinfo, int reg)
357 struct atiixp_info *sc = devinfo;
358 uint32_t data;
359 int timeout;
361 if (atiixp_waitready_codec(sc))
362 return -1;
364 data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
365 ATI_REG_PHYS_OUT_ADDR_EN |
366 ATI_REG_PHYS_OUT_RW | sc->codec_idx;
368 atiixp_wr(sc, ATI_REG_PHYS_OUT_ADDR, data);
370 if (atiixp_waitready_codec(sc))
371 return -1;
373 timeout = 500;
374 do {
375 data = atiixp_rd(sc, ATI_REG_PHYS_IN_ADDR);
376 if (data & ATI_REG_PHYS_IN_READ_FLAG)
377 return data >> ATI_REG_PHYS_IN_DATA_SHIFT;
378 DELAY(1);
379 } while (timeout--);
381 if (reg < 0x7c)
382 device_printf(sc->dev, "codec read timeout! (reg 0x%x)\n", reg);
384 return -1;
387 static int
388 atiixp_wrcd(kobj_t obj, void *devinfo, int reg, uint32_t data)
390 struct atiixp_info *sc = devinfo;
392 if (atiixp_waitready_codec(sc))
393 return -1;
395 data = (data << ATI_REG_PHYS_OUT_DATA_SHIFT) |
396 (((uint32_t)reg) << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
397 ATI_REG_PHYS_OUT_ADDR_EN | sc->codec_idx;
399 atiixp_wr(sc, ATI_REG_PHYS_OUT_ADDR, data);
401 return 0;
404 static kobj_method_t atiixp_ac97_methods[] = {
405 KOBJMETHOD(ac97_read, atiixp_rdcd),
406 KOBJMETHOD(ac97_write, atiixp_wrcd),
407 { 0, 0 }
409 AC97_DECLARE(atiixp_ac97);
412 * Playback / Record channel interface
414 static void *
415 atiixp_chan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
416 struct pcm_channel *c, int dir)
418 struct atiixp_info *sc = devinfo;
419 struct atiixp_chinfo *ch;
420 int num;
422 atiixp_lock(sc);
424 if (dir == PCMDIR_PLAY) {
425 ch = &sc->pch;
426 ch->linkptr_bit = ATI_REG_OUT_DMA_LINKPTR;
427 ch->enable_bit = ATI_REG_CMD_OUT_DMA_EN | ATI_REG_CMD_SEND_EN;
428 ch->flush_bit = ATI_REG_FIFO_OUT_FLUSH;
429 ch->dma_dt_cur_bit = ATI_REG_OUT_DMA_DT_CUR;
430 /* Native 32bit playback working properly */
431 ch->caps_32bit = 1;
432 } else {
433 ch = &sc->rch;
434 ch->linkptr_bit = ATI_REG_IN_DMA_LINKPTR;
435 ch->enable_bit = ATI_REG_CMD_IN_DMA_EN | ATI_REG_CMD_RECEIVE_EN;
436 ch->flush_bit = ATI_REG_FIFO_IN_FLUSH;
437 ch->dma_dt_cur_bit = ATI_REG_IN_DMA_DT_CUR;
438 /* XXX Native 32bit recording appear to be broken */
439 ch->caps_32bit = 1;
442 ch->buffer = b;
443 ch->parent = sc;
444 ch->channel = c;
445 ch->dir = dir;
446 ch->dma_segs = sc->dma_segs;
448 atiixp_unlock(sc);
450 if (sndbuf_alloc(ch->buffer, sc->parent_dmat, sc->bufsz) == -1)
451 return NULL;
453 atiixp_lock(sc);
454 num = sc->registered_channels++;
455 ch->sgd_table = &sc->sgd_table[num * ch->dma_segs];
456 ch->sgd_addr = sc->sgd_addr +
457 (num * ch->dma_segs * sizeof(struct atiixp_dma_op));
458 atiixp_disable_dma(sc, ch);
459 atiixp_unlock(sc);
461 return ch;
464 static int
465 atiixp_chan_setformat(kobj_t obj, void *data, uint32_t format)
467 struct atiixp_chinfo *ch = data;
468 struct atiixp_info *sc = ch->parent;
469 uint32_t value;
471 atiixp_lock(sc);
472 if (ch->dir == PCMDIR_REC) {
473 value = atiixp_rd(sc, ATI_REG_CMD);
474 value &= ~ATI_REG_CMD_INTERLEAVE_IN;
475 if ((format & AFMT_32BIT) == 0)
476 value |= ATI_REG_CMD_INTERLEAVE_IN;
477 atiixp_wr(sc, ATI_REG_CMD, value);
478 } else {
479 value = atiixp_rd(sc, ATI_REG_OUT_DMA_SLOT);
480 value &= ~ATI_REG_OUT_DMA_SLOT_MASK;
481 /* We do not have support for more than 2 channels, _yet_. */
482 value |= ATI_REG_OUT_DMA_SLOT_BIT(3) |
483 ATI_REG_OUT_DMA_SLOT_BIT(4);
484 value |= 0x04 << ATI_REG_OUT_DMA_THRESHOLD_SHIFT;
485 atiixp_wr(sc, ATI_REG_OUT_DMA_SLOT, value);
486 value = atiixp_rd(sc, ATI_REG_CMD);
487 value &= ~ATI_REG_CMD_INTERLEAVE_OUT;
488 if ((format & AFMT_32BIT) == 0)
489 value |= ATI_REG_CMD_INTERLEAVE_OUT;
490 atiixp_wr(sc, ATI_REG_CMD, value);
491 value = atiixp_rd(sc, ATI_REG_6CH_REORDER);
492 value &= ~ATI_REG_6CH_REORDER_EN;
493 atiixp_wr(sc, ATI_REG_6CH_REORDER, value);
495 ch->fmt = format;
496 atiixp_unlock(sc);
498 return 0;
501 static int
502 atiixp_chan_setspeed(kobj_t obj, void *data, uint32_t spd)
504 /* XXX We're supposed to do VRA/DRA processing right here */
505 return ATI_IXP_BASE_RATE;
508 static int
509 atiixp_chan_setblocksize(kobj_t obj, void *data, uint32_t blksz)
511 struct atiixp_chinfo *ch = data;
512 struct atiixp_info *sc = ch->parent;
514 if (blksz > (sc->bufsz / ch->dma_segs))
515 blksz = sc->bufsz / ch->dma_segs;
517 sndbuf_resize(ch->buffer, ch->dma_segs, blksz);
519 return sndbuf_getblksz(ch->buffer);
522 static void
523 atiixp_buildsgdt(struct atiixp_chinfo *ch)
525 uint32_t addr, blksz;
526 int i;
528 addr = sndbuf_getbufaddr(ch->buffer);
529 blksz = sndbuf_getblksz(ch->buffer);
531 for (i = 0; i < ch->dma_segs; i++) {
532 ch->sgd_table[i].addr = htole32(addr + (i * blksz));
533 ch->sgd_table[i].status = htole16(0);
534 ch->sgd_table[i].size = htole16(blksz >> 2);
535 ch->sgd_table[i].next = htole32((uint32_t)ch->sgd_addr +
536 (((i + 1) % ch->dma_segs) *
537 sizeof(struct atiixp_dma_op)));
541 static int
542 atiixp_chan_trigger(kobj_t obj, void *data, int go)
544 struct atiixp_chinfo *ch = data;
545 struct atiixp_info *sc = ch->parent;
546 uint32_t value;
548 atiixp_lock(sc);
550 switch (go) {
551 case PCMTRIG_START:
552 atiixp_flush_dma(sc, ch);
553 atiixp_buildsgdt(ch);
554 atiixp_wr(sc, ch->linkptr_bit, 0);
555 atiixp_enable_dma(sc, ch);
556 atiixp_wr(sc, ch->linkptr_bit,
557 (uint32_t)ch->sgd_addr | ATI_REG_LINKPTR_EN);
558 break;
559 case PCMTRIG_STOP:
560 case PCMTRIG_ABORT:
561 atiixp_disable_dma(sc, ch);
562 atiixp_flush_dma(sc, ch);
563 break;
564 default:
565 atiixp_unlock(sc);
566 return 0;
567 break;
570 /* Update bus busy status */
571 value = atiixp_rd(sc, ATI_REG_IER);
572 if (atiixp_rd(sc, ATI_REG_CMD) & (
573 ATI_REG_CMD_SEND_EN | ATI_REG_CMD_RECEIVE_EN |
574 ATI_REG_CMD_SPDF_OUT_EN))
575 value |= ATI_REG_IER_SET_BUS_BUSY;
576 else
577 value &= ~ATI_REG_IER_SET_BUS_BUSY;
578 atiixp_wr(sc, ATI_REG_IER, value);
580 atiixp_unlock(sc);
582 return 0;
585 static int
586 atiixp_chan_getptr(kobj_t obj, void *data)
588 struct atiixp_chinfo *ch = data;
589 struct atiixp_info *sc = ch->parent;
590 uint32_t addr, align, retry, sz;
591 volatile uint32_t ptr;
593 addr = sndbuf_getbufaddr(ch->buffer);
594 align = (ch->fmt & AFMT_32BIT) ? 7 : 3;
595 retry = 100;
596 sz = sndbuf_getblksz(ch->buffer) * ch->dma_segs;
598 atiixp_lock(sc);
599 do {
600 ptr = atiixp_rd(sc, ch->dma_dt_cur_bit);
601 if (ptr < addr)
602 continue;
603 ptr -= addr;
604 if (ptr < sz && !(ptr & align))
605 break;
606 } while (--retry);
607 atiixp_unlock(sc);
609 #if 0
610 if (retry != 100) {
611 device_printf(sc->dev,
612 "%saligned hwptr: dir=PCMDIR_%s ptr=%u fmt=0x%08x retry=%d\n",
613 (ptr & align) ? "un" : "",
614 (ch->dir == PCMDIR_PLAY) ? "PLAY" : "REC", ptr,
615 ch->fmt, 100 - retry);
617 #endif
619 return (retry > 0) ? ptr : 0;
622 static struct pcmchan_caps *
623 atiixp_chan_getcaps(kobj_t obj, void *data)
625 struct atiixp_chinfo *ch = data;
627 if (ch->caps_32bit)
628 return &atiixp_caps_32bit;
629 return &atiixp_caps;
632 static kobj_method_t atiixp_chan_methods[] = {
633 KOBJMETHOD(channel_init, atiixp_chan_init),
634 KOBJMETHOD(channel_setformat, atiixp_chan_setformat),
635 KOBJMETHOD(channel_setspeed, atiixp_chan_setspeed),
636 KOBJMETHOD(channel_setblocksize, atiixp_chan_setblocksize),
637 KOBJMETHOD(channel_trigger, atiixp_chan_trigger),
638 KOBJMETHOD(channel_getptr, atiixp_chan_getptr),
639 KOBJMETHOD(channel_getcaps, atiixp_chan_getcaps),
640 { 0, 0 }
642 CHANNEL_DECLARE(atiixp_chan);
645 * PCI driver interface
647 static void
648 atiixp_intr(void *p)
650 struct atiixp_info *sc = p;
651 uint32_t status, enable, detected_codecs;
653 atiixp_lock(sc);
654 status = atiixp_rd(sc, ATI_REG_ISR);
656 if (status == 0) {
657 atiixp_unlock(sc);
658 return;
661 if ((status & ATI_REG_ISR_IN_STATUS) && sc->rch.channel) {
662 atiixp_unlock(sc);
663 chn_intr(sc->rch.channel);
664 atiixp_lock(sc);
666 if ((status & ATI_REG_ISR_OUT_STATUS) && sc->pch.channel) {
667 atiixp_unlock(sc);
668 chn_intr(sc->pch.channel);
669 atiixp_lock(sc);
672 #if 0
673 if (status & ATI_REG_ISR_IN_XRUN) {
674 device_printf(sc->dev,
675 "Receive IN XRUN interrupt\n");
677 if (status & ATI_REG_ISR_OUT_XRUN) {
678 device_printf(sc->dev,
679 "Receive OUT XRUN interrupt\n");
681 #endif
683 if (status & CODEC_CHECK_BITS) {
684 /* mark missing codecs as not ready */
685 detected_codecs = status & CODEC_CHECK_BITS;
686 sc->codec_not_ready_bits |= detected_codecs;
688 /* disable detected interupt sources */
689 enable = atiixp_rd(sc, ATI_REG_IER);
690 enable &= ~detected_codecs;
691 atiixp_wr(sc, ATI_REG_IER, enable);
694 /* acknowledge */
695 atiixp_wr(sc, ATI_REG_ISR, status);
696 atiixp_unlock(sc);
699 static void
700 atiixp_dma_cb(void *p, bus_dma_segment_t *bds, int a, int b)
702 struct atiixp_info *sc = (struct atiixp_info *)p;
703 sc->sgd_addr = bds->ds_addr;
706 static void
707 atiixp_chip_pre_init(struct atiixp_info *sc)
709 uint32_t value;
711 atiixp_lock(sc);
713 /* disable interrupts */
714 atiixp_disable_interrupts(sc);
716 /* clear all DMA enables (preserving rest of settings) */
717 value = atiixp_rd(sc, ATI_REG_CMD);
718 value &= ~(ATI_REG_CMD_IN_DMA_EN | ATI_REG_CMD_OUT_DMA_EN |
719 ATI_REG_CMD_SPDF_OUT_EN );
720 atiixp_wr(sc, ATI_REG_CMD, value);
722 /* reset aclink */
723 atiixp_reset_aclink(sc);
725 sc->codec_not_ready_bits = 0;
727 /* enable all codecs to interrupt as well as the new frame interrupt */
728 atiixp_wr(sc, ATI_REG_IER, CODEC_CHECK_BITS);
730 atiixp_unlock(sc);
733 static void
734 atiixp_chip_post_init(void *arg)
736 struct atiixp_info *sc = (struct atiixp_info *)arg;
737 uint32_t subdev;
738 int i, timeout, found;
739 char status[SND_STATUSLEN];
741 atiixp_lock(sc);
743 if (sc->delayed_attach.ich_func) {
744 config_intrhook_disestablish(&sc->delayed_attach);
745 sc->delayed_attach.ich_func = NULL;
748 /* wait for the interrupts to happen */
749 timeout = 100;
750 while (--timeout) {
751 snd_mtxsleep(sc, sc->lock, 0, "ixpslp", 1);
752 if (sc->codec_not_ready_bits)
753 break;
756 atiixp_disable_interrupts(sc);
758 if (timeout == 0) {
759 device_printf(sc->dev,
760 "WARNING: timeout during codec detection; "
761 "codecs might be present but haven't interrupted\n");
762 atiixp_unlock(sc);
763 goto postinitbad;
766 found = 0;
769 * ATI IXP can have upto 3 codecs, but single codec should be
770 * suffice for now.
772 if (!(sc->codec_not_ready_bits &
773 ATI_REG_ISR_CODEC0_NOT_READY)) {
774 /* codec 0 present */
775 sc->codec_found++;
776 sc->codec_idx = 0;
777 found++;
780 if (!(sc->codec_not_ready_bits &
781 ATI_REG_ISR_CODEC1_NOT_READY)) {
782 /* codec 1 present */
783 sc->codec_found++;
786 if (!(sc->codec_not_ready_bits &
787 ATI_REG_ISR_CODEC2_NOT_READY)) {
788 /* codec 2 present */
789 sc->codec_found++;
792 atiixp_unlock(sc);
794 if (found == 0)
795 goto postinitbad;
797 /* create/init mixer */
798 sc->codec = AC97_CREATE(sc->dev, sc, atiixp_ac97);
799 if (sc->codec == NULL)
800 goto postinitbad;
802 subdev = (pci_get_subdevice(sc->dev) << 16) | pci_get_subvendor(sc->dev);
803 switch (subdev) {
804 case 0x11831043: /* ASUS A6R */
805 case 0x2043161f: /* Maxselect x710s - http://maxselect.ru/ */
806 ac97_setflags(sc->codec, ac97_getflags(sc->codec) | AC97_F_EAPD_INV);
807 break;
808 default:
809 break;
812 mixer_init(sc->dev, ac97_getmixerclass(), sc->codec);
814 if (pcm_register(sc->dev, sc, ATI_IXP_NPCHAN, ATI_IXP_NRCHAN))
815 goto postinitbad;
817 for (i = 0; i < ATI_IXP_NPCHAN; i++)
818 pcm_addchan(sc->dev, PCMDIR_PLAY, &atiixp_chan_class, sc);
819 for (i = 0; i < ATI_IXP_NRCHAN; i++)
820 pcm_addchan(sc->dev, PCMDIR_REC, &atiixp_chan_class, sc);
822 ksnprintf(status, SND_STATUSLEN, "at memory 0x%lx irq %ld %s",
823 rman_get_start(sc->reg), rman_get_start(sc->irq),
824 PCM_KLDSTRING(snd_atiixp));
826 pcm_setstatus(sc->dev, status);
828 atiixp_lock(sc);
829 atiixp_enable_interrupts(sc);
830 atiixp_unlock(sc);
832 return;
834 postinitbad:
835 atiixp_release_resource(sc);
838 static void
839 atiixp_release_resource(struct atiixp_info *sc)
841 if (sc == NULL)
842 return;
843 if (sc->codec) {
844 ac97_destroy(sc->codec);
845 sc->codec = NULL;
847 if (sc->ih) {
848 bus_teardown_intr(sc->dev, sc->irq, sc->ih);
849 sc->ih = NULL;
851 if (sc->reg) {
852 bus_release_resource(sc->dev, sc->regtype, sc->regid, sc->reg);
853 sc->reg = NULL;
855 if (sc->irq) {
856 bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irqid, sc->irq);
857 sc->irq = NULL;
859 if (sc->parent_dmat) {
860 bus_dma_tag_destroy(sc->parent_dmat);
861 sc->parent_dmat = NULL;
863 if (sc->sgd_dmamap)
864 bus_dmamap_unload(sc->sgd_dmat, sc->sgd_dmamap);
865 if (sc->sgd_table) {
866 bus_dmamem_free(sc->sgd_dmat, sc->sgd_table, sc->sgd_dmamap);
867 sc->sgd_table = NULL;
869 sc->sgd_dmamap = NULL;
870 if (sc->sgd_dmat) {
871 bus_dma_tag_destroy(sc->sgd_dmat);
872 sc->sgd_dmat = NULL;
874 if (sc->lock) {
875 snd_mtxfree(sc->lock);
876 sc->lock = NULL;
880 static int
881 atiixp_pci_probe(device_t dev)
883 int i;
884 uint16_t devid, vendor;
886 vendor = pci_get_vendor(dev);
887 devid = pci_get_device(dev);
888 for (i = 0; i < sizeof(atiixp_hw)/sizeof(atiixp_hw[0]); i++) {
889 if (vendor == atiixp_hw[i].vendor &&
890 devid == atiixp_hw[i].devid) {
891 device_set_desc(dev, atiixp_hw[i].desc);
892 return BUS_PROBE_DEFAULT;
896 return ENXIO;
899 static int
900 atiixp_pci_attach(device_t dev)
902 struct atiixp_info *sc;
903 int i;
905 if ((sc = kmalloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) {
906 device_printf(dev, "cannot allocate softc\n");
907 return ENXIO;
910 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
911 sc->dev = dev;
913 * Default DMA segments per playback / recording channel
915 sc->dma_segs = ATI_IXP_DMA_CHSEGS;
917 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
918 pci_enable_busmaster(dev);
920 sc->regid = PCIR_BAR(0);
921 sc->regtype = SYS_RES_MEMORY;
922 sc->reg = bus_alloc_resource_any(dev, sc->regtype, &sc->regid,
923 RF_ACTIVE);
925 if (!sc->reg) {
926 device_printf(dev, "unable to allocate register space\n");
927 goto bad;
930 sc->st = rman_get_bustag(sc->reg);
931 sc->sh = rman_get_bushandle(sc->reg);
933 sc->bufsz = pcm_getbuffersize(dev, 4096, ATI_IXP_DEFAULT_BUFSZ, 65536);
935 sc->irqid = 0;
936 sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
937 RF_ACTIVE | RF_SHAREABLE);
938 if (!sc->irq ||
939 snd_setup_intr(dev, sc->irq, INTR_MPSAFE,
940 atiixp_intr, sc, &sc->ih)) {
941 device_printf(dev, "unable to map interrupt\n");
942 goto bad;
946 * Let the user choose the best DMA segments.
948 if (resource_int_value(device_get_name(dev),
949 device_get_unit(dev), "dma_segs",
950 &i) == 0) {
951 if (i < ATI_IXP_DMA_CHSEGS_MIN)
952 i = ATI_IXP_DMA_CHSEGS_MIN;
953 if (i > ATI_IXP_DMA_CHSEGS_MAX)
954 i = ATI_IXP_DMA_CHSEGS_MAX;
955 sc->dma_segs = i;
959 * round the value to the nearest ^2
961 i = 0;
962 while (sc->dma_segs >> i)
963 i++;
964 sc->dma_segs = 1 << (i - 1);
965 if (sc->dma_segs < ATI_IXP_DMA_CHSEGS_MIN)
966 sc->dma_segs = ATI_IXP_DMA_CHSEGS_MIN;
967 else if (sc->dma_segs > ATI_IXP_DMA_CHSEGS_MAX)
968 sc->dma_segs = ATI_IXP_DMA_CHSEGS_MAX;
971 * DMA tag for scatter-gather buffers and link pointers
973 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
974 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
975 /*highaddr*/BUS_SPACE_MAXADDR,
976 /*filter*/NULL, /*filterarg*/NULL,
977 /*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
978 /*flags*/0,
979 &sc->parent_dmat) != 0) {
980 device_printf(dev, "unable to create dma tag\n");
981 goto bad;
984 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0,
985 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT,
986 /*highaddr*/BUS_SPACE_MAXADDR,
987 /*filter*/NULL, /*filterarg*/NULL,
988 /*maxsize*/sc->dma_segs * ATI_IXP_NCHANS *
989 sizeof(struct atiixp_dma_op),
990 /*nsegments*/1, /*maxsegz*/0x3ffff,
991 /*flags*/0,
992 &sc->sgd_dmat) != 0) {
993 device_printf(dev, "unable to create dma tag\n");
994 goto bad;
997 if (bus_dmamem_alloc(sc->sgd_dmat, (void **)&sc->sgd_table,
998 BUS_DMA_NOWAIT, &sc->sgd_dmamap) == -1)
999 goto bad;
1001 if (bus_dmamap_load(sc->sgd_dmat, sc->sgd_dmamap, sc->sgd_table,
1002 sc->dma_segs * ATI_IXP_NCHANS *
1003 sizeof(struct atiixp_dma_op),
1004 atiixp_dma_cb, sc, 0))
1005 goto bad;
1008 atiixp_chip_pre_init(sc);
1010 sc->delayed_attach.ich_func = atiixp_chip_post_init;
1011 sc->delayed_attach.ich_arg = sc;
1012 if (cold == 0 ||
1013 config_intrhook_establish(&sc->delayed_attach) != 0) {
1014 sc->delayed_attach.ich_func = NULL;
1015 atiixp_chip_post_init(sc);
1018 return 0;
1020 bad:
1021 atiixp_release_resource(sc);
1022 return ENXIO;
1025 static int
1026 atiixp_pci_detach(device_t dev)
1028 int r;
1029 struct atiixp_info *sc;
1031 sc = pcm_getdevinfo(dev);
1032 if (sc != NULL) {
1033 if (sc->codec != NULL) {
1034 r = pcm_unregister(dev);
1035 if (r)
1036 return r;
1038 sc->codec = NULL;
1039 atiixp_disable_interrupts(sc);
1040 atiixp_release_resource(sc);
1041 kfree(sc, M_DEVBUF);
1043 return 0;
1046 static int
1047 atiixp_pci_suspend(device_t dev)
1049 struct atiixp_info *sc = pcm_getdevinfo(dev);
1050 uint32_t value;
1052 /* quickly disable interrupts and save channels active state */
1053 atiixp_lock(sc);
1054 atiixp_disable_interrupts(sc);
1055 value = atiixp_rd(sc, ATI_REG_CMD);
1056 sc->pch.active = (value & ATI_REG_CMD_SEND_EN) ? 1 : 0;
1057 sc->rch.active = (value & ATI_REG_CMD_RECEIVE_EN) ? 1 : 0;
1058 atiixp_unlock(sc);
1060 /* stop everything */
1061 if (sc->pch.channel && sc->pch.active)
1062 atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_STOP);
1063 if (sc->rch.channel && sc->rch.active)
1064 atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_STOP);
1066 /* power down aclink and pci bus */
1067 atiixp_lock(sc);
1068 value = atiixp_rd(sc, ATI_REG_CMD);
1069 value |= ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET;
1070 atiixp_wr(sc, ATI_REG_CMD, ATI_REG_CMD_POWERDOWN);
1071 pci_set_powerstate(dev, PCI_POWERSTATE_D3);
1072 atiixp_unlock(sc);
1074 return 0;
1077 static int
1078 atiixp_pci_resume(device_t dev)
1080 struct atiixp_info *sc = pcm_getdevinfo(dev);
1082 atiixp_lock(sc);
1083 /* power up pci bus */
1084 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
1085 pci_enable_io(dev, SYS_RES_MEMORY);
1086 pci_enable_busmaster(dev);
1087 /* reset / power up aclink */
1088 atiixp_reset_aclink(sc);
1089 atiixp_unlock(sc);
1091 if (mixer_reinit(dev) == -1) {
1092 device_printf(dev, "unable to reinitialize the mixer\n");
1093 return ENXIO;
1097 * Resume channel activities. Reset channel format regardless
1098 * of its previous state.
1100 if (sc->pch.channel) {
1101 if (sc->pch.fmt)
1102 atiixp_chan_setformat(NULL, &sc->pch, sc->pch.fmt);
1103 if (sc->pch.active)
1104 atiixp_chan_trigger(NULL, &sc->pch, PCMTRIG_START);
1106 if (sc->rch.channel) {
1107 if (sc->rch.fmt)
1108 atiixp_chan_setformat(NULL, &sc->rch, sc->rch.fmt);
1109 if (sc->rch.active)
1110 atiixp_chan_trigger(NULL, &sc->rch, PCMTRIG_START);
1113 /* enable interrupts */
1114 atiixp_lock(sc);
1115 atiixp_enable_interrupts(sc);
1116 atiixp_unlock(sc);
1118 return 0;
1121 static device_method_t atiixp_methods[] = {
1122 DEVMETHOD(device_probe, atiixp_pci_probe),
1123 DEVMETHOD(device_attach, atiixp_pci_attach),
1124 DEVMETHOD(device_detach, atiixp_pci_detach),
1125 DEVMETHOD(device_suspend, atiixp_pci_suspend),
1126 DEVMETHOD(device_resume, atiixp_pci_resume),
1127 { 0, 0 }
1130 static driver_t atiixp_driver = {
1131 "pcm",
1132 atiixp_methods,
1133 PCM_SOFTC_SIZE,
1136 DRIVER_MODULE(snd_atiixp, pci, atiixp_driver, pcm_devclass, 0, 0);
1137 MODULE_DEPEND(snd_atiixp, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
1138 MODULE_VERSION(snd_atiixp, 1);