FreeBSD kernel sound device code
atiixp.c
Go to the documentation of this file.
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
71
72SND_DECLARE_FILE("$FreeBSD$");
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
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
100 bus_addr_t sgd_addr;
102 uint32_t blksz, blkcnt;
103 uint32_t ptr, prevptr;
104 uint32_t fmt;
105 uint32_t flags;
107};
108
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;
121 void *ih;
123
127 struct intr_config_hook delayed_attach;
128
129 uint32_t bufsz;
131 uint32_t blkcnt;
133
134 struct mtx *lock;
135 struct callout poll_timer;
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
163};
164
165static struct pcmchan_caps atiixp_caps = {
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" },
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
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 */
229
231
232 /*
233 * Disable / ignore internal xrun/spdf interrupt flags
234 * since it doesn't interest us (for now).
235 */
236#if 1
239#else
242
245#endif
246
248}
249
250static void
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
262{
263 uint32_t value, timeout;
264
265 /* if power is down, power it up */
268 /* explicitly enable power */
269 value &= ~ATI_REG_CMD_POWERDOWN;
271
272 /* have to wait at least 10 usec for it to initialise */
273 DELAY(20);
274 }
275
276 /* perform a soft reset */
280
281 /* need to read the CMD reg and wait aprox. 10 usec to init */
283 DELAY(20);
284
285 /* clear soft reset flag again */
287 value &= ~ATI_REG_CMD_AC_SOFT_RESET;
289
290 /* check if the ac-link is working; reset device otherwise */
291 timeout = 10;
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;
302
303 /* need to read CMD again and wait again (clocking in issue?) */
305 DELAY(20);
306
307 /* assert aclink reset again */
311
312 /* check if its active now */
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 */
327}
328
329static void
331{
333}
334
335static void
337{
338 uint32_t value;
339
341 if (!(value & ch->enable_bit)) {
342 value |= ch->enable_bit;
344 }
345}
346
347static void
349{
350 uint32_t value;
351
353 if (value & ch->enable_bit) {
354 value &= ~ch->enable_bit;
356 }
357}
358
359/*
360 * AC97 interface
361 */
362static int
364{
365 int timeout = 500;
366
367 do {
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
385 return (-1);
386
389
391
393 return (-1);
394
395 timeout = 500;
396 do {
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
415 return (-1);
416
418 (((uint32_t)reg) << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
420
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),
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;
452 /* Native 32bit playback working properly */
453 ch->caps_32bit = 1;
454 } else {
455 ch = &sc->rch;
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++;
479 ch->sgd_addr = sc->sgd_addr + (num * ATI_IXP_DMA_CHSEGS_MAX *
480 sizeof(struct atiixp_dma_op));
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) {
497 value &= ~ATI_REG_CMD_INTERLEAVE_IN;
498 if ((format & AFMT_32BIT) == 0)
501 } else {
503 value &= ~ATI_REG_OUT_DMA_SLOT_MASK;
504 /* We do not have support for more than 2 channels, _yet_. */
510 value &= ~ATI_REG_CMD_INTERLEAVE_OUT;
511 if ((format & AFMT_32BIT) == 0)
515 value &= ~ATI_REG_6CH_REORDER_EN;
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
533 uint32_t blksz, uint32_t blkcnt)
534{
535 struct atiixp_chinfo *ch = data;
536 struct atiixp_info *sc = ch->parent;
537
539
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
577
578 return (ch->blksz);
579}
580
581static void
583{
584 struct atiixp_info *sc = ch->parent;
585 uint32_t addr, blksz, blkcnt;
586 int i;
587
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
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;
616 sz = ch->blkcnt * ch->blksz;
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
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
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*/,
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:
736 atiixp_wr(sc, ch->linkptr_bit, 0);
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,
767 }
768 }
770 break;
771 case PCMTRIG_STOP:
772 case PCMTRIG_ABORT:
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,
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 */
818 else
819 value &= ~ATI_REG_IER_SET_BUS_BUSY;
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),
864};
865CHANNEL_DECLARE(atiixp_chan);
866
867/*
868 * PCI driver interface
869 */
870static void
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 }
883
884 if (status == 0) {
885 atiixp_unlock(sc);
886 return;
887 }
888
891 trigger |= 1;
894 trigger |= 2;
895
896#if 0
898 device_printf(sc->dev,
899 "Recieve IN XRUN interrupt\n");
900 }
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 */
914 enable &= ~detected_codecs;
916 wakeup(sc);
917 }
918
919 /* acknowledge */
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
938{
939 uint32_t value;
940
941 atiixp_lock(sc);
942
943 /* disable interrupts */
945
946 /* clear all DMA enables (preserving rest of settings) */
951
952 /* reset aclink */
954
955 sc->codec_not_ready_bits = 0;
956
957 /* enable all codecs to interrupt as well as the new frame interrupt */
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) {
990 sc->polling = 0;
991 DELAY(1000);
992 } else {
994 sc->polling = 1;
995 DELAY(1000);
996 }
997 }
998 atiixp_unlock(sc);
999
1000 return (err);
1001}
1002
1003static void
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;
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 */
1049 /* codec 0 present */
1050 sc->codec_found++;
1051 sc->codec_idx = 0;
1052 found++;
1053 }
1054
1056 /* codec 1 present */
1057 sc->codec_found++;
1058 }
1059
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/ */
1082 break;
1083 default:
1084 break;
1085 }
1086
1088
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 | CTLFLAG_MPSAFE, sc->dev,
1100 sizeof(sc->dev), 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)
1111 atiixp_unlock(sc);
1112
1113 return;
1114
1115postinitbad:
1117}
1118
1119static void
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
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
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
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);
1250 else if (sc->blkcnt > ATI_IXP_DMA_CHSEGS_MAX)
1252
1253 } else
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,
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,
1291 sizeof(struct atiixp_dma_op), atiixp_dma_cb, sc, 0))
1292 goto bad;
1293
1295
1297 sc->delayed_attach.ich_arg = sc;
1298 if (cold == 0 ||
1299 config_intrhook_establish(&sc->delayed_attach) != 0) {
1300 sc->delayed_attach.ich_func = NULL;
1302 }
1303
1304 return (0);
1305
1306bad:
1308 return (ENXIO);
1309}
1310
1311static int
1313{
1314 int r;
1315 struct atiixp_info *sc;
1316
1317 sc = pcm_getdevinfo(dev);
1318 if (sc != NULL) {
1319 if (sc->codec != NULL) {
1320 r = pcm_unregister(dev);
1321 if (r)
1322 return (r);
1323 }
1324 sc->codec = NULL;
1325 if (sc->st != 0 && sc->sh != 0)
1328 }
1329 return (0);
1330}
1331
1332static int
1334{
1335 struct atiixp_info *sc = pcm_getdevinfo(dev);
1336 uint32_t value;
1337
1338 /* quickly disable interrupts and save channels active state */
1339 atiixp_lock(sc);
1341 atiixp_unlock(sc);
1342
1343 /* stop everything */
1344 if (sc->pch.flags & ATI_IXP_CHN_RUNNING) {
1347 }
1348 if (sc->rch.flags & ATI_IXP_CHN_RUNNING) {
1351 }
1352
1353 /* power down aclink and pci bus */
1354 atiixp_lock(sc);
1358 atiixp_unlock(sc);
1359
1360 return (0);
1361}
1362
1363static int
1365{
1366 struct atiixp_info *sc = pcm_getdevinfo(dev);
1367
1368 atiixp_lock(sc);
1369 /* reset / power up aclink */
1371 atiixp_unlock(sc);
1372
1373 if (mixer_reinit(dev) == -1) {
1374 device_printf(dev, "unable to reinitialize the mixer\n");
1375 return (ENXIO);
1376 }
1377
1378 /*
1379 * Resume channel activities. Reset channel format regardless
1380 * of its previous state.
1381 */
1382 if (sc->pch.channel != NULL) {
1383 if (sc->pch.fmt != 0)
1384 atiixp_chan_setformat(NULL, &sc->pch, sc->pch.fmt);
1385 if (sc->pch.flags & ATI_IXP_CHN_SUSPEND) {
1386 sc->pch.flags &= ~ATI_IXP_CHN_SUSPEND;
1388 }
1389 }
1390 if (sc->rch.channel != NULL) {
1391 if (sc->rch.fmt != 0)
1392 atiixp_chan_setformat(NULL, &sc->rch, sc->rch.fmt);
1393 if (sc->rch.flags & ATI_IXP_CHN_SUSPEND) {
1394 sc->rch.flags &= ~ATI_IXP_CHN_SUSPEND;
1396 }
1397 }
1398
1399 /* enable interrupts */
1400 atiixp_lock(sc);
1401 if (sc->polling == 0)
1403 atiixp_unlock(sc);
1404
1405 return (0);
1406}
1407
1408static device_method_t atiixp_methods[] = {
1409 DEVMETHOD(device_probe, atiixp_pci_probe),
1410 DEVMETHOD(device_attach, atiixp_pci_attach),
1411 DEVMETHOD(device_detach, atiixp_pci_detach),
1412 DEVMETHOD(device_suspend, atiixp_pci_suspend),
1413 DEVMETHOD(device_resume, atiixp_pci_resume),
1414 { 0, 0 }
1415};
1416
1417static driver_t atiixp_driver = {
1418 "pcm",
1421};
1422
1425MODULE_VERSION(snd_atiixp, 1);
u_int32_t ac97_getflags(struct ac97_info *codec)
Definition: ac97.c:876
kobj_class_t ac97_getmixerclass(void)
Definition: ac97.c:1097
void ac97_destroy(struct ac97_info *codec)
Definition: ac97.c:860
void ac97_setflags(struct ac97_info *codec, u_int32_t val)
Definition: ac97.c:870
#define AC97_CREATE(dev, devinfo, cls)
Definition: ac97.h:89
#define AC97_F_EAPD_INV
Definition: ac97.h:85
u_int32_t data
Definition: ac97_if.m:60
void * devinfo
Definition: ac97_if.m:47
#define ATI_IXP_DMA_RETRY_MAX
Definition: atiixp.c:74
static int atiixp_chan_trigger(kobj_t, void *, int)
Definition: atiixp.c:720
static void atiixp_release_resource(struct atiixp_info *)
Definition: atiixp.c:1120
static kobj_method_t atiixp_ac97_methods[]
Definition: atiixp.c:426
static int atiixp_pci_suspend(device_t)
Definition: atiixp.c:1333
#define atiixp_chan_active(sc)
Definition: atiixp.c:686
static int sysctl_atiixp_polling(SYSCTL_HANDLER_ARGS)
Definition: atiixp.c:964
#define ATI_IXP_BUFSZ_MAX
Definition: atiixp.c:77
static uint32_t atiixp_fmt_32bit[]
Definition: atiixp.c:148
static void atiixp_disable_interrupts(struct atiixp_info *)
Definition: atiixp.c:251
static void atiixp_enable_interrupts(struct atiixp_info *)
Definition: atiixp.c:220
static uint32_t atiixp_chan_setspeed(kobj_t, void *, uint32_t)
Definition: atiixp.c:525
static int atiixp_pci_detach(device_t)
Definition: atiixp.c:1312
#define ATI_IXP_BLK_MIN
Definition: atiixp.c:80
static struct pcmchan_caps atiixp_caps_32bit
Definition: atiixp.c:159
char * desc
Definition: atiixp.c:174
#define atiixp_wr(_sc, _reg, _val)
Definition: atiixp.c:141
#define ATI_IXP_BLK_ALIGN
Definition: atiixp.c:81
#define atiixp_rd(_sc, _reg)
Definition: atiixp.c:139
static void atiixp_flush_dma(struct atiixp_chinfo *)
Definition: atiixp.c:330
uint16_t vendor
Definition: atiixp.c:172
#define ATI_IXP_CHN_RUNNING
Definition: atiixp.c:83
static int atiixp_wrcd(kobj_t, void *, int, uint32_t)
Definition: atiixp.c:410
#define ATI_IXP_CHN_SUSPEND
Definition: atiixp.c:84
MODULE_VERSION(snd_atiixp, 1)
static void atiixp_buildsgdt(struct atiixp_chinfo *)
Definition: atiixp.c:582
static __inline uint32_t atiixp_dmapos(struct atiixp_chinfo *)
Definition: atiixp.c:608
static __inline int atiixp_poll_channel(struct atiixp_chinfo *ch)
Definition: atiixp.c:663
static int atiixp_chan_setfragments(kobj_t, void *, uint32_t, uint32_t)
Definition: atiixp.c:532
static struct pcmchan_caps atiixp_caps
Definition: atiixp.c:165
static struct pcmchan_caps * atiixp_chan_getcaps(kobj_t, void *)
Definition: atiixp.c:845
#define ATI_IXP_BUFSZ_DEFAULT
Definition: atiixp.c:78
SND_DECLARE_FILE("$FreeBSD$")
static int atiixp_pci_attach(device_t)
Definition: atiixp.c:1190
static void atiixp_chip_post_init(void *)
Definition: atiixp.c:1004
CHANNEL_DECLARE(atiixp_chan)
static void atiixp_reset_aclink(struct atiixp_info *)
Definition: atiixp.c:261
static int atiixp_waitready_codec(struct atiixp_info *)
Definition: atiixp.c:363
static uint32_t atiixp_fmt[]
Definition: atiixp.c:154
static void atiixp_dma_cb(void *, bus_dma_segment_t *, int, int)
Definition: atiixp.c:930
MODULE_DEPEND(snd_atiixp, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER)
static void * atiixp_chan_init(kobj_t, void *, struct snd_dbuf *, struct pcm_channel *, int)
Definition: atiixp.c:437
static void atiixp_enable_dma(struct atiixp_chinfo *)
Definition: atiixp.c:336
static const struct @3 atiixp_hw[]
static void atiixp_intr(void *)
Definition: atiixp.c:871
#define ATI_IXP_BUFSZ_MIN
Definition: atiixp.c:76
#define atiixp_unlock(_sc)
Definition: atiixp.c:145
#define atiixp_lock(_sc)
Definition: atiixp.c:144
static kobj_method_t atiixp_chan_methods[]
Definition: atiixp.c:854
static void atiixp_disable_dma(struct atiixp_chinfo *)
Definition: atiixp.c:348
static void atiixp_chip_pre_init(struct atiixp_info *)
Definition: atiixp.c:937
static uint32_t atiixp_chan_setblocksize(kobj_t, void *, uint32_t)
Definition: atiixp.c:571
static int atiixp_pci_probe(device_t)
Definition: atiixp.c:1171
static device_method_t atiixp_methods[]
Definition: atiixp.c:1408
static driver_t atiixp_driver
Definition: atiixp.c:1417
DRIVER_MODULE(snd_atiixp, pci, atiixp_driver, pcm_devclass, 0, 0)
static int atiixp_pci_resume(device_t)
Definition: atiixp.c:1364
uint16_t devid
Definition: atiixp.c:173
static int atiixp_rdcd(kobj_t, void *, int)
Definition: atiixp.c:378
static int atiixp_chan_setformat(kobj_t, void *, uint32_t)
Definition: atiixp.c:488
AC97_DECLARE(atiixp_ac97)
static uint32_t atiixp_chan_getptr(kobj_t, void *)
Definition: atiixp.c:828
static void atiixp_poll_callback(void *arg)
Definition: atiixp.c:690
#define ATI_REG_OUT_DMA_DT_CUR
Definition: atiixp.h:164
#define ATI_REG_OUT_DMA_THRESHOLD_SHIFT
Definition: atiixp.h:159
#define ATI_REG_OUT_DMA_SLOT_BIT(x)
Definition: atiixp.h:156
#define ATI_REG_CMD_RECEIVE_EN
Definition: atiixp.h:99
#define ATI_REG_LINKPTR_EN
Definition: atiixp.h:189
#define ATI_REG_CMD_IN_DMA_EN
Definition: atiixp.h:106
#define CODEC_CHECK_BITS
Definition: atiixp.h:203
#define ATI_REG_CMD_SPDF_OUT_EN
Definition: atiixp.h:102
#define ATI_REG_CMD_SEND_EN
Definition: atiixp.h:100
#define ATI_REG_6CH_REORDER
Definition: atiixp.h:181
#define ATI_REG_PHYS_OUT_DATA_SHIFT
Definition: atiixp.h:134
#define ATI_REG_ISR_CODEC0_NOT_READY
Definition: atiixp.h:77
#define ATI_REG_ISR
Definition: atiixp.h:68
#define ATI_REG_ISR_IN_STATUS
Definition: atiixp.h:70
#define ATI_REG_IER_IN_XRUN_EN
Definition: atiixp.h:83
#define ATI_IXP_NPCHAN
Definition: atiixp.h:39
#define ATI_REG_CMD_INTERLEAVE_IN
Definition: atiixp.h:117
#define ATI_IXP_NCHANS
Definition: atiixp.h:41
#define ATI_REG_ISR_CODEC2_NOT_READY
Definition: atiixp.h:79
#define ATI_REG_PHYS_IN_ADDR
Definition: atiixp.h:136
#define ATI_REG_FIFO_IN_FLUSH
Definition: atiixp.h:186
#define ATI_REG_OUT_DMA_LINKPTR
Definition: atiixp.h:161
#define ATI_REG_FIFO_FLUSH
Definition: atiixp.h:184
#define ATI_REG_ISR_OUT_STATUS
Definition: atiixp.h:72
#define ATI_REG_CMD_OUT_DMA_EN
Definition: atiixp.h:107
#define ATI_REG_ISR_CODEC1_NOT_READY
Definition: atiixp.h:78
#define ATI_REG_OUT_DMA_SLOT
Definition: atiixp.h:155
#define ATI_REG_CMD_POWERDOWN
Definition: atiixp.h:98
#define ATI_REG_IER
Definition: atiixp.h:82
#define ATI_IXP_BASE_RATE
Definition: atiixp.h:58
#define ATI_REG_IER_SPDF_STATUS_EN
Definition: atiixp.h:88
#define ATI_REG_IER_OUT_XRUN_EN
Definition: atiixp.h:85
#define ATI_IXP_DMA_CHSEGS_MAX
Definition: atiixp.h:49
#define ATI_IXP_DMA_CHSEGS
Definition: atiixp.h:47
#define ATI_REG_PHYS_OUT_ADDR_EN
Definition: atiixp.h:132
#define ATI_REG_PHYS_OUT_ADDR_SHIFT
Definition: atiixp.h:133
#define ATI_IXP_SB600_ID
Definition: atiixp.h:56
#define ATI_IXP_DMA_CHSEGS_MIN
Definition: atiixp.h:48
#define ATI_REG_IN_DMA_DT_CUR
Definition: atiixp.h:152
#define ATI_REG_IER_SPDF_XRUN_EN
Definition: atiixp.h:87
#define ATI_REG_PHYS_IN_READ_FLAG
Definition: atiixp.h:137
#define ATI_REG_CMD
Definition: atiixp.h:97
#define ATI_VENDOR_ID
Definition: atiixp.h:51
#define ATI_REG_CMD_AC_SYNC
Definition: atiixp.h:126
#define ATI_IXP_NRCHAN
Definition: atiixp.h:40
#define ATI_IXP_300_ID
Definition: atiixp.h:54
#define ATI_REG_FIFO_OUT_FLUSH
Definition: atiixp.h:185
#define ATI_REG_PHYS_OUT_ADDR
Definition: atiixp.h:129
#define ATI_REG_ISR_IN_XRUN
Definition: atiixp.h:69
#define ATI_REG_PHYS_OUT_RW
Definition: atiixp.h:131
#define ATI_REG_CMD_ACLINK_ACTIVE
Definition: atiixp.h:124
#define ATI_REG_CMD_INTERLEAVE_OUT
Definition: atiixp.h:118
#define ATI_REG_IER_SET_BUS_BUSY
Definition: atiixp.h:95
#define ATI_REG_IER_IO_STATUS_EN
Definition: atiixp.h:84
#define ATI_IXP_200_ID
Definition: atiixp.h:53
#define ATI_REG_CMD_AC_SOFT_RESET
Definition: atiixp.h:125
#define ATI_REG_PHYS_IN_DATA_SHIFT
Definition: atiixp.h:139
#define ATI_IXP_400_ID
Definition: atiixp.h:55
#define ATI_REG_ISR_OUT_XRUN
Definition: atiixp.h:71
#define ATI_REG_CMD_AC_RESET
Definition: atiixp.h:127
#define ATI_REG_IN_DMA_LINKPTR
Definition: atiixp.h:149
uint32_t format
Definition: audio_dai_if.m:39
METHOD int trigger
Definition: audio_dai_if.m:62
int go
Definition: audio_dai_if.m:64
unsigned int sndbuf_getspd(struct snd_dbuf *b)
Definition: buffer.c:373
int sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, int dmaflags, unsigned int size)
Definition: buffer.c:93
unsigned int sndbuf_getblkcnt(struct snd_dbuf *b)
Definition: buffer.c:391
bus_addr_t sndbuf_getbufaddr(struct snd_dbuf *buf)
Definition: buffer.c:66
unsigned int sndbuf_getalign(struct snd_dbuf *b)
Definition: buffer.c:385
unsigned int sndbuf_getblksz(struct snd_dbuf *b)
Definition: buffer.c:403
unsigned int sndbuf_getmaxsize(struct snd_dbuf *b)
Definition: buffer.c:441
int sndbuf_resize(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz)
Definition: buffer.c:164
void chn_intr(struct pcm_channel *c)
Definition: channel.c:660
#define PCMDIR_PLAY
Definition: channel.h:339
#define PCMTRIG_START
Definition: channel.h:344
#define PCMTRIG_STOP
Definition: channel.h:347
#define PCMDIR_REC
Definition: channel.h:341
#define PCMTRIG_COMMON(x)
Definition: channel.h:350
#define PCMTRIG_ABORT
Definition: channel.h:348
struct pcm_channel * c
Definition: channel_if.m:106
METHOD int free
Definition: channel_if.m:110
struct snd_dbuf * b
Definition: channel_if.m:105
uint32_t spd
Definition: dsp.c:394
int max
Definition: dsp.c:392
uint32_t value
Definition: hdaa.c:58
uint8_t enable
Definition: hdac.c:213
uint8_t reg
Definition: hdac.c:211
int blksz
Definition: hdac_if.m:64
int dir
Definition: hdac_if.m:45
int blkcnt
Definition: hdac_if.m:65
uint8_t r
uint16_t retry
#define KOBJMETHOD_END
Definition: midi.c:76
int mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
Definition: mixer.c:725
int mixer_reinit(device_t dev)
Definition: mixer.c:860
unsigned dev
Definition: mixer_if.m:59
bool * status
u_int32_t val
uint64_t * addr
#define PCIR_BAR(x)
void * snd_mtxcreate(const char *desc, const char *type)
Definition: sound.c:88
void * pcm_getdevinfo(device_t dev)
Definition: sound.c:832
int pcm_setstatus(device_t dev, char *str)
Definition: sound.c:766
devclass_t pcm_devclass
Definition: sound.c:49
void snd_mtxfree(void *m)
Definition: sound.c:98
int pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo)
Definition: sound.c:692
int pcm_unregister(device_t dev)
Definition: sound.c:1170
int pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
Definition: sound.c:1080
int snd_setup_intr(device_t dev, struct resource *res, int flags, driver_intr_t hand, void *param, void **cookiep)
Definition: sound.c:117
unsigned int pcm_getbuffersize(device_t dev, unsigned int minbufsz, unsigned int deflt, unsigned int maxbufsz)
Definition: sound.c:840
#define PCM_KLDSTRING(a)
Definition: sound.h:619
#define SND_FORMAT(f, c, e)
Definition: sound.h:238
#define SOUND_PREFVER
Definition: sound.h:103
#define SOUND_MAXVER
Definition: sound.h:104
#define SOUND_MINVER
Definition: sound.h:102
#define PCM_SOFTC_SIZE
Definition: sound.h:96
#define SND_STATUSLEN
Definition: sound.h:98
#define AFMT_32BIT
Definition: sound.h:189
Definition: ac97.c:59
uint32_t ptr
Definition: atiixp.c:103
uint32_t blksz
Definition: atiixp.c:102
uint32_t prevptr
Definition: atiixp.c:103
uint32_t flags
Definition: atiixp.c:105
bus_addr_t sgd_addr
Definition: atiixp.c:100
uint32_t enable_bit
Definition: atiixp.c:101
struct atiixp_dma_op * sgd_table
Definition: atiixp.c:99
struct pcm_channel * channel
Definition: atiixp.c:97
uint32_t fmt
Definition: atiixp.c:104
uint32_t linkptr_bit
Definition: atiixp.c:101
uint32_t flush_bit
Definition: atiixp.c:101
uint32_t blkcnt
Definition: atiixp.c:102
int caps_32bit
Definition: atiixp.c:106
struct snd_dbuf * buffer
Definition: atiixp.c:96
struct atiixp_info * parent
Definition: atiixp.c:98
uint32_t dt_cur_bit
Definition: atiixp.c:101
volatile uint32_t addr
Definition: atiixp.c:87
volatile uint32_t next
Definition: atiixp.c:90
volatile uint16_t status
Definition: atiixp.c:88
volatile uint16_t size
Definition: atiixp.c:89
bus_dma_tag_t sgd_dmat
Definition: atiixp.c:115
int registered_channels
Definition: atiixp.c:132
struct resource * irq
Definition: atiixp.c:119
struct resource * reg
Definition: atiixp.c:119
struct ac97_info * codec
Definition: atiixp.c:122
bus_space_handle_t sh
Definition: atiixp.c:113
int irqid
Definition: atiixp.c:120
int poll_ticks
Definition: atiixp.c:136
struct atiixp_chinfo pch
Definition: atiixp.c:124
struct intr_config_hook delayed_attach
Definition: atiixp.c:127
bus_addr_t sgd_addr
Definition: atiixp.c:117
bus_space_tag_t st
Definition: atiixp.c:112
device_t dev
Definition: atiixp.c:110
bus_dmamap_t sgd_dmamap
Definition: atiixp.c:116
struct callout poll_timer
Definition: atiixp.c:135
uint32_t codec_not_ready_bits
Definition: atiixp.c:130
uint32_t codec_idx
Definition: atiixp.c:130
uint32_t bufsz
Definition: atiixp.c:129
struct mtx * lock
Definition: atiixp.c:134
void * ih
Definition: atiixp.c:121
int polling
Definition: atiixp.c:136
uint32_t codec_found
Definition: atiixp.c:130
uint32_t blkcnt
Definition: atiixp.c:131
struct atiixp_dma_op * sgd_table
Definition: atiixp.c:126
int regtype
Definition: atiixp.c:120
int regid
Definition: atiixp.c:120
struct atiixp_chinfo rch
Definition: atiixp.c:125
bus_dma_tag_t parent_dmat
Definition: atiixp.c:114
const void * req